Pagination<T> and PaginationController<T> slice a list into pages and (optionally) render a button strip with prev / next / page-number controls. Use the data-only Pagination<T> if you want to drive your own UI; use PaginationController<T> when you also want Luna's button rendering.

The recommended pattern reuses existing VisualElements instead of recreating them on each page change — fewer allocations, smoother updates.
A tiny adapter that binds/unbinds a single Label to one row of data:
using UnityEngine.UIElements;
namespace CupkekGames.UITK.Demo.Components
{
public class LabelWithBinding
{
private Label _label;
public LabelWithBinding(Label label) { _label = label; }
public void Bind(string data) { _label.text = data; }
public void Unbind() { _label.text = ""; }
}
}public class PaginationDemo : UIViewComponent
{
[Header("Pagination Settings")]
[SerializeField] private int _itemPerPage = 3;
[SerializeField] private int _maxButtonAmount = 5;
[SerializeField] private UIColorName _baseButtonColor = UIColorName.BASE;
[SerializeField] private UIColorName _activeButtonColor = UIColorName.PRIMARY;
[Header("Pagination Data")]
[SerializeField] private int _dataAmount = 200;
private PaginationController<string> _pagination;
private List<string> _sourceList = new();
private List<LabelWithBinding> _uiController = new();
private VisualElement _container;
protected override void Awake()
{
base.Awake();
for (int i = 0; i < _dataAmount; i++)
_sourceList.Add("Element-" + i);
_container = ParentElement.Q<VisualElement>("PaginationElementsContainer");
for (int i = 0; i < _itemPerPage; i++)
{
Label label = new Label();
_container.Add(label);
_uiController.Add(new LabelWithBinding(label));
}
VisualElement paginationElement = ParentElement.Q<VisualElement>("Pagination");
_pagination = new(
_sourceList, _itemPerPage, paginationElement,
_baseButtonColor, _activeButtonColor, _maxButtonAmount
);
}
private void OnEnable() => _pagination.OnPageChange += OnPageChange;
private void OnDisable() => _pagination.OnPageChange -= OnPageChange;
protected virtual void Start() => _pagination.GoToPage(0);
private void OnPageChange(int page)
{
List<string> currentPage = _pagination.GetCurrentPageElements();
for (int i = 0; i < _pagination.ItemsPerPage; i++)
{
LabelWithBinding controller = _uiController[i];
controller.Unbind();
if (i >= currentPage.Count) continue;
controller.Bind(currentPage[i]);
}
}
}The full demo lives in the Showcase sample under Storybook/Components/Pagination/.
The data-only base class — no UI dependency.
public Pagination(List<T> data, int itemsPerPage)| Method | Returns | Description |
|---|---|---|
NextPage() | bool | Advance one page. Returns true if the page actually changed. |
PreviousPage() | bool | Step back one page. |
GoToPage(int pageIndex) | bool | Jump to a specific page. |
GetCurrentPageElements() | List<T> | Items on the current page. |
GetStartIndex(int page) | int | First-element index of the given page in the source list. |
public event Action<int> OnPageChange; // new page indexSubclass of Pagination<T> that also renders a button strip.
// Data-only; wire up UI later via SetUI.
public PaginationController(List<T> data, int itemsPerPage);
// Data + UI in one call.
public PaginationController(
List<T> data,
int itemsPerPage,
VisualElement parent,
UIColorName normal,
UIColorName active,
int maxButtonAmount
);| Method | Description |
|---|---|
SetUI(VisualElement parent, UIColorName normal, UIColorName active, int maxButtonAmount) | Attach (or re-attach) the button strip to a parent. |
UpdateUI() | Rebuild the button strip — call after the data list changes length. |
Show() | Show the button strip. |
Hide() | Hide the button strip. |
Settings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction