Getting Started

Get up and running with mantine-select-async-paginate in minutes. This guide covers installation, basic setup, and your first async select component.

Prerequisites

Before installing, ensure your project meets these requirements:

  • React 18.0.0 or higher
  • Mantine 7.0.0 or 8.0.0
  • TypeScript (optional but recommended)
  • Node.js 16 or higher

Installation

Install the package using your preferred package manager:

npm

npm install mantine-select-async-paginate

yarn

yarn add mantine-select-async-paginate

pnpm

pnpm add mantine-select-async-paginate

Basic Setup

Make sure you have Mantine properly set up in your project. If not, follow the Mantine installation guide first.

// Required imports
import { MantineProvider } from '@mantine/core';
import '@mantine/core/styles.css';

// Your app wrapper
function App() {
  return (
    <MantineProvider>
      {/* Your app content */}
    </MantineProvider>
  );
}

Your First Async Select

Here's a simple example to get you started with AsyncPaginateSelect:

import { useState } from 'react';
import { AsyncPaginateSelect } from 'mantine-select-async-paginate';

function MyComponent() {
  const [value, setValue] = useState(null);
  
  // Define your loadOptions function
  const loadOptions = async (search, loadedOptions, additional) => {
    // Fetch data from your API
    const response = await fetch(`/api/search?q=${search}&page=${additional?.page || 1}`);
    const data = await response.json();
    
    return {
      options: data.items.map(item => ({
        value: item.id,
        label: item.name,
      })),
      hasMore: data.hasMore,
      additional: { page: (additional?.page || 1) + 1 }
    };
  };
  
  return (
    <AsyncPaginateSelect
      label="Select an option"
      placeholder="Type to search..."
      value={value}
      onChange={setValue}
      loadOptions={loadOptions}
      defaultOptions // Load options when dropdown opens
      cacheOptions // Cache results for better performance
      clearable // Allow clearing selection
    />
  );
}

Multi-Select Usage

For multi-select functionality, you can either use the dedicated component or the multiple prop:

Option 1: Dedicated Component

import { AsyncPaginateMultiSelect } from 'mantine-select-async-paginate';

function MultiSelectExample() {
  const [values, setValues] = useState([]);
  
  return (
    <AsyncPaginateMultiSelect
      label="Select multiple options"
      value={values}
      onChange={setValues}
      loadOptions={loadOptions}
      maxSelectedValues={5}
      excludeSelected={true}
    />
  );
}

Option 2: Multiple Prop

<AsyncPaginateSelect
  multiple={true}
  value={values}
  onChange={setValues}
  loadOptions={loadOptions}
  maxSelectedValues={5}
/>

Understanding loadOptions

The `loadOptions` function is the heart of the component. It receives three parameters:

async function loadOptions(
  search: string,              // Current search query
  loadedOptions: Option[],     // Already loaded options
  additional?: any             // Custom data for pagination
) {
  // Your API call logic here
  
  return {
    options: [                 // Array of options
      { value: '1', label: 'Option 1' },
      { value: '2', label: 'Option 2' },
    ],
    hasMore: true,             // Whether more data is available
    additional: { page: 2 }    // Data to pass to next call
  };
}

Common Patterns

Pagination with offset/limit

const loadOptions = async (search, loadedOptions, additional) => {
  const offset = additional?.offset || 0;
  const limit = 20;
  
  const response = await fetch(
    `/api/items?search=${search}&offset=${offset}&limit=${limit}`
  );
  const { items, total } = await response.json();
  
  return {
    options: items.map(item => ({
      value: item.id,
      label: item.name
    })),
    hasMore: offset + limit < total,
    additional: { offset: offset + limit }
  };
};

Page-based pagination

const loadOptions = async (search, loadedOptions, additional) => {
  const page = additional?.page || 1;
  
  const response = await fetch(
    `/api/items?search=${search}&page=${page}&per_page=20`
  );
  const { items, total_pages } = await response.json();
  
  return {
    options: items.map(item => ({
      value: item.id,
      label: item.name
    })),
    hasMore: page < total_pages,
    additional: { page: page + 1 }
  };
};

Next Steps