
A primitive that creates all the reactive data to manage your pagination:
createPagination
- Provides an array with the properties to fill your pagination with and a page setter/getter.
createInfiniteScroll
- Provides an easy way to implement infinite scrolling.
Installation
npm install @solid-primitives/pagination
yarn add @solid-primitives/pagination
pnpm add @solid-primitives/pagination
Provides an array with the properties to fill your pagination with and a page setter/getter.
How to use it
type PaginationOptions = {
pages: number;
maxPages?: number;
initialPage?: number;
showFirst?: boolean | ((page: number, pages: number) => boolean);
showPrev?: boolean | ((page: number, pages: number) => boolean);
showNext?: boolean | ((page: number, pages: number) => boolean);
showLast?: boolean | ((page: number, pages: number) => boolean);
firstContent?: JSX.Element;
prevContent?: JSX.Element;
nextContent?: JSX.Element;
lastContent?: JSX.Element;
};
const [props, page, setPage] = createPagination({ pages: 3 });
While the preferred structure is links or buttons (if only client-side) inside a nav element, you can use arbitrary components, e.g. using your favorite UI component library (as long as it supports the same handlers and properties as DOM nodes, which it probably should). The props objects for each page will be reused in order to grant maximum performance using the <For>
flow component to iterate over the props:
const [paginationProps, page, setPage] = createPagination({ pages: 100 });
createEffect(() => {
page();
});
return (
<nav class="pagination">
<For each={paginationProps()}>{props => <button {...props} />}</For>
</nav>
);
In order to allow linking the pages manually, there is a non-enumerable page property in the props object:
const [paginationProps, page, setPage] = createPagination({ pages: 100 });
createEffect(() => {
page();
});
return (
<nav class="pagination">
<ul>
<For each={paginationProps()}>
{props => (
<li>
<A href={`?page=${props.page}`} {...props} />
</li>
)}
</For>
</ul>
</nav>
);
TODO
- Jump over multiple pages (e.g. +10/-10)
- options for aria-labels
- optional: touch controls
Demo
You may view a working example here:
https://primitives.solidjs.community/playground/pagination/
createInfiniteScroll
Combines createResource
with IntersectionObserver
to provide an easy way to implement infinite scrolling.
How to use it
const [pages, setEl, { end }] = createInfiniteScroll(fetcher);
return (
<div>
<For each={pages()}>{item => <h4>{item}</h4>}</For>
<Show when={!end()}>
<h1 ref={setEl}>Loading...</h1>
</Show>
</div>
);
Or as a directive:
const [pages, infiniteScrollLoader, { end }] = createInfiniteScroll(fetcher);
return (
<div>
<For each={pages()}>{item => <h4>{item}</h4>}</For>
<Show when={!end()}>
<h1 use:infiniteScrollLoader>Loading...</h1>
</Show>
</div>
);
Definition
function createInfiniteScroll<T>(fetcher: (page: number) => Promise<T[]>): [
pages: Accessor<T[]>,
loader: Directive<true>,
options: {
page: Accessor<number>;
setPage: Setter<number>;
setPages: Setter<T[]>;
end: Accessor<boolean>;
setEnd: Setter<boolean>;
},
];
Changelog
See CHANGELOG.md