Primitives / State
Start with one: a page
ts
import { Schema } from 'effect'
import type { HtmlBuilder } from 'foldkit/html'
import { Bundle } from 'foldkit-bundle'
import { Pagination, PaginationMessage, pageCount, range } from 'foldkit-primitives/state'
const Page = Bundle.compose({}).pipe(
Bundle.withChild('paging', Pagination, { args: { perPage: 20 } }),
)
type Model = typeof Page.Model.Type
type Message = typeof Page.Message.Type
const { placements } = Page
const config = placements.complete({
init: () => placements.initial({}),
update: placements.update(model => ({ model })),
view: (model: Model, h: HtmlBuilder<Message>) =>
h.nav(
[],
range(1, (pageCount(model.paging) ?? 0) + 1).map(page =>
h.button(
[h.OnClick(Page.Message.GotPagingMessage({ message: PaginationMessage.GoToPage({ page }) }))],
[String(page)],
),
),
),
subscriptions: placements.subscriptions(),
})total is null until the application learns it and sends SetTotal;
pageCount is null until then, and offset(model) is the first item's index
for a slice or a query. Every transition clamps: past the last page lands on
it, below one lands on one, and a smaller total pulls the page back.
SetPerPage ignores a non-positive size and SetTotal a negative total.