react-antd-admin-panel
Version:
Modern TypeScript-first React admin panel builder with Ant Design 6
1 lines • 30.6 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../../src/list/index.ts"],"sourcesContent":["import React from 'react';\nimport { Table, TableProps, Avatar, Tag, Button, Space, Tooltip, Input, Row, Col, Popconfirm } from 'antd';\nimport type { ColumnsType, ColumnType } from 'antd/es/table';\nimport { SearchOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons';\nimport { BaseBuilder } from '../base/BaseBuilder';\nimport type { ComponentConfig } from '../types';\nimport { Get } from '../http/Get';\n\nexport interface ListColumnConfig<T = any> {\n key: string;\n title: string;\n dataIndex?: string | string[];\n width?: number | string;\n fixed?: 'left' | 'right';\n align?: 'left' | 'center' | 'right';\n sorter?: boolean | ((a: T, b: T) => number);\n filters?: { text: string; value: any }[];\n render?: (value: any, record: T, index: number) => React.ReactNode;\n ellipsis?: boolean;\n hidden?: boolean;\n searchable?: boolean;\n}\n\nexport interface ListActionConfig<T = any> {\n key: string;\n label: string;\n icon?: React.ReactNode;\n onClick: (record: T, index: number) => void;\n danger?: boolean;\n disabled?: boolean | ((record: T) => boolean);\n confirm?: string;\n tooltip?: string;\n}\n\nexport interface BulkActionConfig<T = any> {\n key: string;\n label: string;\n icon?: React.ReactNode;\n onClick: (selectedRows: T[], selectedKeys: React.Key[]) => void | Promise<void>;\n danger?: boolean;\n confirm?: string;\n}\n\nexport interface ListHeaderConfig {\n title?: string;\n showSearch?: boolean;\n searchPlaceholder?: string;\n onSearch?: (value: string) => void;\n showCreate?: boolean;\n createLabel?: string;\n onCreate?: () => void;\n showRefresh?: boolean;\n onRefresh?: () => void;\n extra?: React.ReactNode;\n}\n\nexport interface ListConfig<T = any> extends ComponentConfig {\n columns?: ListColumnConfig<T>[];\n actions?: ListActionConfig<T>[];\n bulkActions?: BulkActionConfig<T>[];\n dataSource?: T[];\n rowKey?: string | ((record: T) => string);\n loading?: boolean;\n pagination?: false | {\n pageSize?: number;\n current?: number;\n total?: number;\n showSizeChanger?: boolean;\n showQuickJumper?: boolean;\n showTotal?: (total: number, range: [number, number]) => React.ReactNode;\n onChange?: (page: number, pageSize: number) => void;\n };\n size?: 'small' | 'middle' | 'large';\n bordered?: boolean;\n showHeader?: boolean;\n sticky?: boolean;\n scroll?: { x?: number | string; y?: number | string };\n rowSelection?: {\n type?: 'checkbox' | 'radio';\n selectedRowKeys?: React.Key[];\n onChange?: (selectedRowKeys: React.Key[], selectedRows: T[]) => void;\n };\n expandable?: {\n expandedRowRender?: (record: T) => React.ReactNode;\n rowExpandable?: (record: T) => boolean;\n };\n onRow?: (record: T, index?: number) => React.HTMLAttributes<HTMLElement>;\n // New advanced config\n header?: ListHeaderConfig;\n get?: Get<T[]>;\n emptyText?: string;\n virtual?: boolean;\n virtualHeight?: number;\n virtualScrollX?: number | string;\n}\n\n/**\n * List Builder - Table/List component with builder pattern\n * Wrapper for Ant Design Table with fluent API\n * \n * @example\n * // Basic usage\n * const userList = new List<User>()\n * .rowKey('id')\n * .column('name', 'Name')\n * .column('email', 'Email')\n * .tagColumn('role', 'Role', { admin: 'red', user: 'blue' })\n * .action('edit', 'Edit', (record) => navigate(`/users/${record.id}`))\n * .pagination({ pageSize: 10 })\n * .dataSource(users);\n * \n * @example\n * // With header controls and bulk actions\n * const userList = new List<User>()\n * .rowKey('id')\n * .header({\n * title: 'Users',\n * showSearch: true,\n * onSearch: (q) => setSearch(q),\n * showCreate: true,\n * onCreate: () => navigate('/users/new'),\n * showRefresh: true,\n * onRefresh: () => refresh(),\n * })\n * .selectable('checkbox')\n * .bulkAction('delete', 'Delete Selected', (rows) => deleteUsers(rows), { danger: true, confirm: 'Delete?' })\n * .column('name', 'Name')\n * .dataSource(users);\n */\nexport class List<T extends object = any> extends BaseBuilder<ListConfig<T>> {\n // These are used by selectable() for initial state, but actual state is managed in ListComponent\n private _selectedRowKeys: React.Key[] = [];\n\n constructor() {\n super();\n this._config.columns = [];\n this._config.actions = [];\n this._config.bulkActions = [];\n }\n\n /**\n * Set the data source\n */\n dataSource(data: T[]): this {\n this._config.dataSource = data;\n return this;\n }\n\n /**\n * Set the row key field or function\n */\n rowKey(key: string | ((record: T) => string)): this {\n this._config.rowKey = key;\n return this;\n }\n\n /**\n * Add a column to the table\n * Supports multiple signatures:\n * - column(key, title) - basic column\n * - column(key, title, config) - column with options\n * - column(key, title, render) - column with custom render\n * - column(key, title, render, config) - column with render and options\n */\n column(\n key: string,\n title: string,\n renderOrConfig?: ((value: any, record: T, index: number) => React.ReactNode) | Partial<ListColumnConfig<T>>,\n configIfRender?: Partial<ListColumnConfig<T>>\n ): this {\n const columnConfig: ListColumnConfig<T> = {\n key,\n title,\n dataIndex: key,\n };\n\n if (typeof renderOrConfig === 'function') {\n columnConfig.render = renderOrConfig;\n // If render function is provided, merge any additional config\n if (configIfRender) {\n Object.assign(columnConfig, configIfRender);\n }\n } else if (renderOrConfig) {\n Object.assign(columnConfig, renderOrConfig);\n }\n\n this._config.columns!.push(columnConfig);\n return this;\n }\n\n /**\n * Add an avatar column\n */\n avatarColumn(key: string, title: string = 'Avatar', size: number = 40): this {\n this._config.columns!.push({\n key,\n title,\n dataIndex: key,\n width: size + 32,\n render: (url: string) => React.createElement(Avatar, { src: url, size }),\n });\n return this;\n }\n\n /**\n * Add a tag column\n */\n tagColumn(\n key: string,\n title: string,\n colorMap?: Record<string, string>,\n options?: Omit<ListColumnConfig<T>, 'key' | 'title' | 'dataIndex' | 'render'>\n ): this {\n this._config.columns!.push({\n key,\n title,\n dataIndex: key,\n ...options,\n render: (value: string) => {\n const color = colorMap?.[value] || 'default';\n return React.createElement(Tag, { color }, value);\n },\n });\n return this;\n }\n\n /**\n * Add a date column with formatting\n */\n dateColumn(\n key: string,\n title: string,\n format: 'date' | 'datetime' | 'relative' = 'date',\n options?: Omit<ListColumnConfig<T>, 'key' | 'title' | 'dataIndex' | 'render'>\n ): this {\n this._config.columns!.push({\n key,\n title,\n dataIndex: key,\n ...options,\n render: (value: string | Date) => {\n if (!value) return '-';\n const date = new Date(value);\n if (format === 'datetime') {\n return date.toLocaleString();\n } else if (format === 'relative') {\n const diff = Date.now() - date.getTime();\n const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n if (days === 0) return 'Today';\n if (days === 1) return 'Yesterday';\n if (days < 7) return `${days} days ago`;\n return date.toLocaleDateString();\n }\n return date.toLocaleDateString();\n },\n });\n return this;\n }\n\n /**\n * Add a boolean column with Yes/No or custom labels\n */\n booleanColumn(\n key: string,\n title: string,\n options?: { trueLabel?: string; falseLabel?: string; trueColor?: string; falseColor?: string }\n ): this {\n const { trueLabel = 'Yes', falseLabel = 'No', trueColor = 'green', falseColor = 'default' } = options || {};\n this._config.columns!.push({\n key,\n title,\n dataIndex: key,\n render: (value: boolean) =>\n React.createElement(Tag, { color: value ? trueColor : falseColor }, value ? trueLabel : falseLabel),\n });\n return this;\n }\n\n /**\n * Add an action button\n */\n action(\n key: string,\n label: string,\n onClick: (record: T, index: number) => void,\n options?: Partial<Omit<ListActionConfig<T>, 'key' | 'label' | 'onClick'>>\n ): this {\n this._config.actions!.push({\n key,\n label,\n onClick,\n ...options,\n });\n return this;\n }\n\n /**\n * Set loading state\n */\n loading(value: boolean = true): this {\n this._config.loading = value;\n return this;\n }\n\n /**\n * Configure pagination\n */\n pagination(config: false | ListConfig<T>['pagination']): this {\n this._config.pagination = config;\n return this;\n }\n\n /**\n * Set table size\n */\n size(value: 'small' | 'middle' | 'large'): this {\n this._config.size = value;\n return this;\n }\n\n /**\n * Enable bordered style\n */\n bordered(value: boolean = true): this {\n this._config.bordered = value;\n return this;\n }\n\n /**\n * Show/hide header\n */\n showHeader(value: boolean = true): this {\n this._config.showHeader = value;\n return this;\n }\n\n /**\n * Enable sticky header\n */\n sticky(value: boolean = true): this {\n this._config.sticky = value;\n return this;\n }\n\n /**\n * Set scroll dimensions\n */\n scroll(x?: number | string, y?: number | string): this {\n this._config.scroll = { x, y };\n return this;\n }\n\n /**\n * Enable row selection\n */\n rowSelection(config: ListConfig<T>['rowSelection']): this {\n this._config.rowSelection = config;\n return this;\n }\n\n /**\n * Enable row expansion\n */\n expandable(config: ListConfig<T>['expandable']): this {\n this._config.expandable = config;\n return this;\n }\n\n /**\n * Enable row expansion with a render function\n */\n expandableRow(\n render: (record: T) => React.ReactNode,\n isExpandable?: (record: T) => boolean\n ): this {\n this._config.expandable = {\n expandedRowRender: render,\n rowExpandable: isExpandable,\n };\n return this;\n }\n\n /**\n * Set row event handlers\n */\n onRow(handler: (record: T, index?: number) => React.HTMLAttributes<HTMLElement>): this {\n this._config.onRow = handler;\n return this;\n }\n\n /**\n * Configure header controls (search, create, refresh, etc.)\n */\n header(config: ListHeaderConfig): this {\n this._config.header = config;\n return this;\n }\n\n /**\n * Enable simple row selection (state is managed by ListComponent)\n */\n selectable(type: 'checkbox' | 'radio' = 'checkbox'): this {\n this._config.rowSelection = {\n type,\n selectedRowKeys: this._selectedRowKeys,\n onChange: (keys) => {\n this._selectedRowKeys = keys;\n },\n };\n return this;\n }\n\n /**\n * Add a bulk action (for selected rows)\n */\n bulkAction(\n key: string,\n label: string,\n onClick: (selectedRows: T[], selectedKeys: React.Key[]) => void | Promise<void>,\n options?: Partial<Omit<BulkActionConfig<T>, 'key' | 'label' | 'onClick'>>\n ): this {\n this._config.bulkActions!.push({\n key,\n label,\n onClick,\n ...options,\n });\n return this;\n }\n\n /**\n * Set a Get request for data fetching\n */\n get(request: Get<T[]>): this {\n this._config.get = request;\n return this;\n }\n\n /**\n * Set empty state text\n */\n emptyText(text: string): this {\n this._config.emptyText = text;\n return this;\n }\n\n /**\n * Enable virtual scrolling for large datasets\n * @param height - The height of the virtual scroll container (default 400)\n * @param scrollX - The horizontal scroll width (default 'max-content'). Set to calculated width for best performance.\n */\n virtual(height: number = 400, scrollX?: number | string): this {\n this._config.virtual = true;\n this._config.virtualHeight = height;\n if (scrollX !== undefined) {\n this._config.virtualScrollX = scrollX;\n }\n return this;\n }\n\n /**\n * Get the current configuration (for advanced use cases)\n */\n getConfig(): ListConfig<T> {\n // Return the config directly without spreading to preserve reference identity\n // This is important for React.useMemo dependency checks\n return this._config;\n }\n\n /**\n * Render the table component\n */\n render(): React.ReactNode {\n if (this._config.hidden) {\n return null;\n }\n\n // Use a functional component to handle state for selection and header\n return React.createElement(ListComponent, { list: this as List<any> });\n }\n}\n\n/**\n * ListComponent - React component that handles state for the List builder\n * Wrapped in React.memo to prevent unnecessary re-renders\n */\ninterface ListComponentProps<T extends object> {\n list: List<T>;\n}\n\nconst ListComponent = React.memo(function ListComponent<T extends object>({ list }: ListComponentProps<T>): React.ReactElement | null {\n const config = list.getConfig();\n const [selectedRowKeys, setSelectedRowKeys] = React.useState<React.Key[]>([]);\n const [selectedRows, setSelectedRows] = React.useState<T[]>([]);\n const [searchValue, setSearchValue] = React.useState('');\n\n // Memoize columns to prevent rebuilding on every render (critical for virtual scrolling performance)\n const columns = React.useMemo((): ColumnsType<T> => {\n const cols: ColumnsType<T> = [];\n\n // Add data columns\n for (const col of config.columns || []) {\n if (col.hidden) continue;\n\n const column: ColumnType<T> = {\n key: col.key,\n title: col.title,\n dataIndex: col.dataIndex,\n width: col.width,\n fixed: col.fixed,\n align: col.align,\n ellipsis: col.ellipsis,\n render: col.render,\n };\n\n if (col.sorter) {\n column.sorter = col.sorter;\n }\n\n if (col.filters) {\n column.filters = col.filters;\n column.onFilter = (value, record) => {\n const dataIndex = col.dataIndex as string;\n return (record as any)[dataIndex] === value;\n };\n }\n\n cols.push(column);\n }\n\n // Add actions column if there are actions\n if (config.actions && config.actions.length > 0) {\n cols.push({\n key: '_actions',\n title: 'Actions',\n fixed: 'right',\n width: config.actions.length * 80,\n render: (_: any, record: T, index: number) => {\n const buttons = config.actions!.map((action) => {\n const isDisabled = typeof action.disabled === 'function'\n ? action.disabled(record)\n : action.disabled;\n\n // Handle confirm dialog\n if (action.confirm) {\n return React.createElement(\n Popconfirm,\n {\n key: action.key,\n title: action.confirm,\n onConfirm: () => action.onClick(record, index),\n okText: 'Yes',\n cancelText: 'No',\n },\n React.createElement(\n Button,\n {\n type: 'link',\n size: 'small',\n danger: action.danger,\n disabled: isDisabled,\n icon: action.icon,\n },\n action.label\n )\n );\n }\n\n const button = React.createElement(\n Button,\n {\n key: action.key,\n type: 'link',\n size: 'small',\n danger: action.danger,\n disabled: isDisabled,\n icon: action.icon,\n onClick: () => action.onClick(record, index),\n },\n action.label\n );\n\n if (action.tooltip) {\n return React.createElement(Tooltip, { key: action.key, title: action.tooltip }, button);\n }\n\n return button;\n });\n\n return React.createElement(Space, { size: 'small' }, ...buttons);\n },\n });\n }\n\n return cols;\n }, [config.columns, config.actions]);\n\n // Memoize row selection onChange handler\n const handleRowSelectionChange = React.useCallback((keys: React.Key[], rows: T[]) => {\n setSelectedRowKeys(keys);\n setSelectedRows(rows);\n config.rowSelection?.onChange?.(keys, rows);\n }, [config.rowSelection]);\n\n // Handle row selection\n const rowSelection = config.rowSelection ? {\n ...config.rowSelection,\n selectedRowKeys,\n onChange: handleRowSelectionChange,\n } : undefined;\n\n // Memoize header rendering\n const headerElement = React.useMemo(() => {\n const header = config.header;\n if (!header) return null;\n\n const hasSelection = selectedRowKeys.length > 0;\n const bulkActions = config.bulkActions || [];\n\n return React.createElement(\n Row,\n { \n justify: 'space-between', \n align: 'middle',\n style: { marginBottom: 16 },\n },\n // Left side: title and bulk actions\n React.createElement(\n Col,\n {},\n React.createElement(\n Space,\n {},\n header.title && React.createElement('span', { \n style: { fontSize: 16, fontWeight: 600 } \n }, header.title),\n hasSelection && React.createElement(\n Tag,\n { color: 'blue' },\n `${selectedRowKeys.length} selected`\n ),\n hasSelection && bulkActions.map(action => {\n if (action.confirm) {\n return React.createElement(\n Popconfirm,\n {\n key: action.key,\n title: action.confirm,\n onConfirm: () => action.onClick(selectedRows, selectedRowKeys),\n okText: 'Yes',\n cancelText: 'No',\n },\n React.createElement(\n Button,\n {\n size: 'small',\n danger: action.danger,\n icon: action.icon,\n },\n action.label\n )\n );\n }\n return React.createElement(\n Button,\n {\n key: action.key,\n size: 'small',\n danger: action.danger,\n icon: action.icon,\n onClick: () => action.onClick(selectedRows, selectedRowKeys),\n },\n action.label\n );\n }),\n ),\n ),\n // Right side: search, create, refresh\n React.createElement(\n Col,\n {},\n React.createElement(\n Space,\n {},\n header.showSearch && React.createElement(\n Input,\n {\n placeholder: header.searchPlaceholder || 'Search...',\n prefix: React.createElement(SearchOutlined),\n value: searchValue,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n setSearchValue(e.target.value);\n header.onSearch?.(e.target.value);\n },\n allowClear: true,\n style: { width: 200 },\n 'aria-label': 'Search',\n }\n ),\n header.showCreate && React.createElement(\n Button,\n {\n type: 'primary',\n icon: React.createElement(PlusOutlined),\n onClick: header.onCreate,\n 'aria-label': header.createLabel ? undefined : 'Create new item',\n },\n header.createLabel || 'Create'\n ),\n header.showRefresh && React.createElement(\n Button,\n {\n icon: React.createElement(ReloadOutlined),\n onClick: header.onRefresh,\n 'aria-label': 'Refresh list',\n }\n ),\n header.extra,\n ),\n ),\n );\n }, [config.header, config.bulkActions, selectedRowKeys, selectedRows, searchValue]);\n\n // Build table props\n const tableProps: TableProps<T> = {\n dataSource: config.dataSource,\n columns,\n rowKey: config.rowKey || 'id',\n loading: config.loading,\n pagination: config.pagination,\n size: config.size,\n bordered: config.bordered,\n showHeader: config.showHeader,\n sticky: config.sticky,\n scroll: config.virtual \n ? { x: config.virtualScrollX || 'max-content', y: config.virtualHeight || 400, ...config.scroll }\n : config.scroll,\n rowSelection,\n expandable: config.expandable,\n onRow: config.onRow,\n locale: config.emptyText ? { emptyText: config.emptyText } : undefined,\n virtual: config.virtual,\n };\n\n return React.createElement(\n React.Fragment,\n {},\n headerElement,\n React.createElement(Table, tableProps as any),\n );\n}) as <T extends object>(props: ListComponentProps<T>) => React.ReactElement | null;\n"],"names":["BaseBuilder","Avatar","Tag","ListComponent","Popconfirm","Button","Tooltip","Space","Row","Col","Input","SearchOutlined","PlusOutlined","ReloadOutlined","Table"],"mappings":"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"}