Invoice history
| Invoice | Status | Amount |
|---|---|---|
| NK-2026-0713 | Paid | $49.00 |
| NK-2026-0612 | Paid | $49.00 |
| NK-2026-0511 | Refunded | $49.00 |
Showing the three most recent of 36 invoices
Caller-owned result context placed beside exactly one typed Pagination.
app/components/nitro_kit/pagination_bar.rbNitroKit::PaginationBar.new { |bar| bar.summary(...); bar.pagination(NitroKit::Pagination.new(...)) { |pagination| ... } }Caller-owned summaries pair with typed Pagination at first, middle, and final page boundaries.
Showing records 1–25 of 287
Showing records 126–150 of 287
Showing records 276–287 of 287
test/dummy/app/components/gallery/components/pagination_bar_page.rbsample("First page", slug: "first") do
render_boundary_bar("first", current: 1, total: 12, range: "1–25", previous: nil, following: 2)
end
sample("Middle page", slug: "middle") do
render_boundary_bar("middle", current: 6, total: 12, range: "126–150", previous: 5, following: 7)
end
sample("Final page", slug: "final") do
render_boundary_bar("final", current: 12, total: 12, range: "276–287", previous: 11, following: nil)
endThe summary may be omitted; when declared it accepts caller text or direct Phlex content.
Showing 26–50 of 418 invoices Filtered
test/dummy/app/components/gallery/components/pagination_bar_page.rbsample("No summary", slug: "none") do
render NitroKit::PaginationBar.new(id: "gallery-pagination-bar-no-summary") do |bar|
bar.pagination(NitroKit::Pagination.new(label: "Compact pages")) do |pagination|
pagination.prev
pagination.page(1, current: true)
pagination.page(2, href: "?page=2")
pagination.next(href: "?page=2")
end
end
end
sample("Phlex summary", slug: "phlex") do
render NitroKit::PaginationBar.new(id: "gallery-pagination-bar-rich-summary") do |bar|
bar.summary do
plain("Showing 26–50 of 418 invoices ")
render NitroKit::Badge.new(
"Filtered",
id: "gallery-pagination-bar-rich-summary-badge",
size: :sm,
variant: :outline
)
end
bar.pagination(NitroKit::Pagination.new(label: "Filtered invoice pages")) do |pagination|
pagination.prev(href: "?status=paid&page=1")
pagination.page(2, current: true)
pagination.next(href: "?status=paid&page=3")
end
end
endLong summaries, omitted ranges, and preserved filter parameters stay outside the component's responsibilities.
Showing users 201–225 of 4,892 matching “international research and production administrators” with active security-key enrollment
test/dummy/app/components/gallery/components/pagination_bar_page.rbrender NitroKit::PaginationBar.new(id: "gallery-pagination-bar-filtered") do |bar|
bar.summary(
"Showing users 201–225 of 4,892 matching “international research and production administrators” " \
"with active security-key enrollment",
html: { id: "gallery-pagination-bar-filtered-summary" },
aria: { live: "polite" }
)
bar.pagination(NitroKit::Pagination.new(label: "Filtered workspace user pages")) do |pagination|
pagination.prev(href: "?query=research&status=active&page=8")
pagination.page(1, href: "?query=research&status=active&page=1")
pagination.ellipsis(label: "Pages 2 through 7 omitted")
pagination.page(8, href: "?query=research&status=active&page=8")
pagination.page(9, current: true)
pagination.page(10, href: "?query=research&status=active&page=10")
pagination.ellipsis(label: "Pages 11 through 195 omitted")
pagination.page(196, href: "?query=research&status=active&page=196")
pagination.next(href: "?query=research&status=active&page=10")
end
endPage 6 of 12 · 287 records
test/dummy/app/components/gallery/components/pagination_bar_page.rbrender NitroKit::PaginationBar.new(id: "gallery-pagination-bar-dense") do |bar|
bar.summary("Page 6 of 12 · 287 records")
bar.pagination(NitroKit::Pagination.new(label: "Dense record pages")) do |pagination|
pagination.prev(href: "?page=5")
12.times do |index|
page = index + 1
pagination.page(page, href: "?page=#{page}", current: page == 6)
end
pagination.next(href: "?page=7")
end
endTable data, captions, counts, and links remain caller-owned around the placement component.
| Invoice | Status | Amount |
|---|---|---|
| NK-2026-0713 | Paid | $49.00 |
| NK-2026-0612 | Paid | $49.00 |
| NK-2026-0511 | Refunded | $49.00 |
Showing the three most recent of 36 invoices
test/dummy/app/components/gallery/components/pagination_bar_page.rbrender NitroKit::Card.new(id: "gallery-pagination-bar-invoices-card") do |card|
card.title("Invoice history", level: 4)
card.body do
render NitroKit::Table.new(id: "gallery-pagination-bar-invoices-table") do |table|
table.caption("Recent workspace invoices")
table.thead do
table.tr do
table.th("Invoice")
table.th("Status")
table.th("Amount", align: :right)
end
end
table.tbody do
Gallery::Data.invoices.each do |invoice|
table.tr do
table.th(invoice.number, scope: :row)
table.td { render NitroKit::Badge.new(invoice.status.to_s.humanize, size: :sm) }
table.td("$#{invoice.amount_cents / 100}.00", align: :right)
end
end
end
end
render NitroKit::PaginationBar.new(id: "gallery-pagination-bar-invoices") do |bar|
bar.summary("Showing the three most recent of 36 invoices")
bar.pagination(NitroKit::Pagination.new(label: "Invoice history pages")) do |pagination|
pagination.prev(href: "?page=11")
pagination.page(1, href: "?page=1")
pagination.ellipsis(label: "Pages 2 through 10 omitted")
pagination.page(11, href: "?page=11")
pagination.page(12, current: true)
pagination.next
end
end
end
endConstructor options, rendered root, closed vocabularies, and compound boundary for this component, exactly as shipped.
docs/component_contracts.md · NitroKit::PaginationBar
id: nildiv[data-nk=pagination-bar]pagination(NitroKit::Pagination) and at most one non-blank summary. The summary announces politely unless the caller supplies its own aria-live; the shadowed Phlex element remains available as html_summary. Counts, routes, and page math remain caller-owned.Application conventions this component belongs to. Each summary is the leading section of its pattern document.
docs/patterns/queryable_collection.md
NitroKit::Table owns no query policy._top.Instructions for coding agents, repeated on every component page so one fetched page has enough context. Humans can usually skip this section.
test/dummy/app/components/gallery/agent_rules.rb
render NitroKit::Button.new("Save", variant: :primary).ArgumentError; this component's accepted options are in the contract above.html: for HTML, aria: for ARIA, and data: for application data. class and style are forbidden, including inside html:.NitroKit::Component::RESERVED_DATA_ATTRIBUTES: data-nk, data-slot, data-variant, data-size, data-nk-escape, data-enhanced, data-state, data-disabled, data-required, data-orientation, data-presentation, data-placement, data-layout, data-side, data-field-type, data-dir, data-gap, data-align, data-justify, data-wrap, data-cols, data-mode, data-key. Do not pass them through data:. data-action, data-controller are additive and compose with Nitro behavior.desperately_need_a_class:. It requires a non-blank String and marks the exception with data-nk-escape="class".data-nk; owned parts emit component-qualified data-slot values such as field-control or card-title. Select on those attributes, never on classes.--nk-* custom properties in an application stylesheet. Variables beginning with --_nk-* are private component mechanics.NitroKit::Flex and NitroKit::Grid for layout. Parents own external placement and available width; components own their intrinsic geometry.data-state when styling or behavior also needs it.