/v1.0

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)}
    />
  );
}