DynamicList
A fully-featured data list component that renders items either from a remote API endpoint or a local data array. Items are composed using a slots system: startSlots appear on the left side of each row and endSlots on the right. Each slot can render text, thumbnails, pills, money amounts, status badges, action buttons, or dropdown menus. A renderItem prop allows a fully custom item renderer. Supports load-more and numbered pagination, search, and filter integration. An imperative ref exposes reloadList.
Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| data | any[] \| null | No | null | Local data array. When provided, no API call is made. |
| listPath | string | No | — | API endpoint path for fetching items. |
| apiBaseUrl | string | No | config urls.apiBase | Base URL for the HTTP client. |
| useAuthToken | boolean | No | false | Uses the authenticated client when true. |
| startSlots | Slot[] | No | [] | Slots rendered at the start (left) of each item row. |
| endSlots | Slot[] | No | [] | Slots rendered at the end (right) of each item row. |
| renderItem | (item, index) => ReactNode | No | — | Fully custom item renderer; overrides the default slot-based layout. |
| isItemClickable | boolean | No | false | Makes each row clickable (pointer cursor). |
| breakpoint | number | No | 800 | Pixel width below which the layout switches to mobile mode. |
| noContentText | string | No | 'No content available' | Message shown when the list is empty. |
| noContentIcon | string | No | 'records' | Icon shown in the empty state. |
| searchTerm | string | No | '' | Search string appended to the API request. |
| filters | any[] | No | [] | Filter objects serialized and appended to the API request. |
| pagination | { page: number } | No | { page: 1 } | Current pagination state (controlled externally). |
| paginationConfig | PaginationConfig | No | — | Pagination mode and options (see below). |
| reloadTrigger | number | No | — | Increment this value to trigger a list reload. |
| onItemClick | (item, index) => void | No | — | Fired when a clickable item row is pressed. |
| onSlotClick | (slot, item) => void | No | — | Fired when a slot is clicked. |
| onActionClick | (actionName, item, index?) => void | No | — | Fired when a slot action button is activated. |
| onItemChangeSuccess | (item, message?) => void | No | — | Fired after a successful remote slot action. |
| onItemChangeError | (item, error) => void | No | — | Fired after a failed remote slot action. |
| onPaginationChange | (pagination) => void | No | — | Fired when the user navigates to a different page. |
| onResetListState | () => void | No | — | Fired when the list triggers a full reset. |
| onLoadingChange | (isLoading) => void | No | — | Fired when the loading state changes. |
| onLoaded | (result) => void | No | — | Fired after data is loaded with the result status and data. |
| containerStyle | React.CSSProperties | No | — | Inline styles for the list container. |
| itemStyle | React.CSSProperties | No | — | Inline styles for each item row. |
| className | string | No | — | CSS class name for the list container. |
PaginationConfig shape
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| mode | 'loadMore' \| 'numbered' \| 'none' | Yes | — | Pagination style. |
| itemsPerPage | number | Yes | — | Number of items per page. |
| loadMoreText | string | No | 'Cargar más' | Label for the load-more button. |
| showFirstLast | boolean | No | — | Show first/last page buttons (numbered mode). |
| showPrevNext | boolean | No | — | Show previous/next buttons (numbered mode). |
Ref API (DynamicListRef)
| Method | Description |
|--------|-------------|
| reloadList() | Resets state and re-fetches data from the API. |
Usage
Remote list with action slots
import DynamicList from '@/components/DynamicList/DynamicList';
const endSlots = [
{
type: 'text',
name: 'status',
},
{
type: 'action',
name: 'edit',
config: {
variant: 'icon',
actionName: 'edit',
buttonIcon: 'edit',
},
},
];
export default function Example() {
return (
<DynamicList
listPath="/v1/products"
useAuthToken
endSlots={endSlots}
onActionClick={(action, item) => console.log(action, item)}
/>
);
}
Local data with numbered pagination
import { useState } from 'react';
import DynamicList from '@/components/DynamicList/DynamicList';
const items = Array.from({ length: 50 }, (_, i) => ({ id: i + 1, name: `Item ${i + 1}` }));
export default function Example() {
const [pagination, setPagination] = useState({ page: 1 });
return (
<DynamicList
data={items}
paginationConfig={{ mode: 'numbered', itemsPerPage: 10 }}
pagination={pagination}
onPaginationChange={(p) => setPagination(p)}
/>
);
}