Pagination
Links between pages of a result set.
<pagination.Pagination>
<pagination.PaginationContent>
<pagination.PaginationItem><pagination.PaginationPrevious href={gx.URL("/?page=1")} /></pagination.PaginationItem>
<pagination.PaginationItem>
<pagination.PaginationLink href={gx.URL("/?page=1")} active>1</pagination.PaginationLink>
</pagination.PaginationItem>
<pagination.PaginationItem>
<pagination.PaginationLink href={gx.URL("/?page=2")}>2</pagination.PaginationLink>
</pagination.PaginationItem>
<pagination.PaginationItem><pagination.PaginationEllipsis /></pagination.PaginationItem>
<pagination.PaginationItem><pagination.PaginationNext href={gx.URL("/?page=2")} /></pagination.PaginationItem>
</pagination.PaginationContent>
</pagination.Pagination>Installation
Run the command in the app module.
gx add paginationThe command also installs button and icons.
The command writes these files.
| File | Path in the app |
|---|---|
Pagination.gx |
ui/pagination/Pagination.gx |
PaginationContent.gx |
ui/pagination/PaginationContent.gx |
PaginationItem.gx |
ui/pagination/PaginationItem.gx |
PaginationLink.gx |
ui/pagination/PaginationLink.gx |
PaginationPrevious.gx |
ui/pagination/PaginationPrevious.gx |
PaginationNext.gx |
ui/pagination/PaginationNext.gx |
PaginationEllipsis.gx |
ui/pagination/PaginationEllipsis.gx |
Pagination.fixtures.go |
ui/pagination/Pagination.fixtures.go |
styles.go |
ui/pagination/styles.go |
PaginationContent.fixtures.go |
ui/pagination/PaginationContent.fixtures.go |
PaginationEllipsis.fixtures.go |
ui/pagination/PaginationEllipsis.fixtures.go |
PaginationItem.fixtures.go |
ui/pagination/PaginationItem.fixtures.go |
PaginationLink.fixtures.go |
ui/pagination/PaginationLink.fixtures.go |
PaginationNext.fixtures.go |
ui/pagination/PaginationNext.fixtures.go |
PaginationPrevious.fixtures.go |
ui/pagination/PaginationPrevious.fixtures.go |
Install button and icons first.
Copy each file to its path in the app. Change each import of a registry package to the path of that package in the app.
package pagination
props {
// Class adds classes to the root element.
Class string = ""
// Children is the content of the navigation: a PaginationContent.
Children gx.Node
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<nav role="navigation" aria-label="pagination" data-slot="pagination" class={gx.Cx("mx-auto flex w-full justify-center", p.Class)} {...p.Attrs}>{p.Children}</nav>package pagination
props {
// Class adds classes to the root element.
Class string = ""
// Children is the pagination items.
Children gx.Node
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<ul data-slot="pagination-content" class={gx.Cx("flex flex-row items-center gap-1", p.Class)} {...p.Attrs}>{p.Children}</ul>package pagination
props {
// Class adds classes to the root element.
Class string = ""
// Children is the content of the item: a link or an ellipsis.
Children gx.Node
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<li data-slot="pagination-item" class={p.Class} {...p.Attrs}>{p.Children}</li>package pagination
import "github.com/alternayte/gx/registry/button"
props {
// Href is the URL of the page.
Href gx.URL
// Active marks the link of the current page. It sets aria-current and the outline style.
Active bool = false
// Size sets the height and padding with a button size. The default is button.Icon, a square
// link.
Size button.Size = button.Icon
// Class adds classes to the root element.
Class string = ""
// Children is the link label, for example the page number.
Children gx.Node
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<a href={p.Href} data-slot="pagination-link" class={p.class()} {...p.attrs()}>{p.Children}</a>package pagination
import "github.com/alternayte/gx/registry/button"
import "github.com/alternayte/gx/registry/icons"
props {
// Href is the URL of the previous page.
Href gx.URL
// Class adds classes to the root element.
Class string = ""
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<PaginationLink href={p.Href} size={button.Md} class={gx.Cx("gap-1 px-2.5 sm:pl-2.5", p.Class)} attrs={p.attrs()}>
<icons.ChevronLeft />
<span class="hidden sm:block">Previous</span>
</PaginationLink>package pagination
import "github.com/alternayte/gx/registry/button"
import "github.com/alternayte/gx/registry/icons"
props {
// Href is the URL of the next page.
Href gx.URL
// Class adds classes to the root element.
Class string = ""
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<PaginationLink href={p.Href} size={button.Md} class={gx.Cx("gap-1 px-2.5 sm:pr-2.5", p.Class)} attrs={p.attrs()}>
<span class="hidden sm:block">Next</span>
<icons.ChevronRight />
</PaginationLink>package pagination
import "github.com/alternayte/gx/registry/icons"
props {
// Class adds classes to the root element.
Class string = ""
// Attrs adds HTML attributes to the root element.
Attrs gx.Attrs = nil
}
<span aria-hidden="true" data-slot="pagination-ellipsis" class={gx.Cx("flex size-9 items-center justify-center", p.Class)} {...p.Attrs}>
<icons.Ellipsis class="size-4" />
<span class="sr-only">More pages</span>
</span>package pagination
import "github.com/alternayte/gx"
var PaginationFixtures = gx.Fixtures[PaginationProps]{
"Trail": {Children: PaginationContent(PaginationContentProps{Children: gx.Frag(
PaginationItem(PaginationItemProps{Children: PaginationPrevious(PaginationPreviousProps{Href: gx.URL("/?page=1")})}),
PaginationItem(PaginationItemProps{Children: PaginationLink(PaginationLinkProps{Href: gx.URL("/?page=1"), Active: true, Children: gx.Text("1")})}),
PaginationItem(PaginationItemProps{Children: PaginationLink(PaginationLinkProps{Href: gx.URL("/?page=2"), Children: gx.Text("2")})}),
PaginationItem(PaginationItemProps{Children: PaginationEllipsis(PaginationEllipsisProps{})}),
PaginationItem(PaginationItemProps{Children: PaginationNext(PaginationNextProps{Href: gx.URL("/?page=2")})}),
)})},
}package pagination
import (
"github.com/alternayte/gx"
"github.com/alternayte/gx/registry/button"
)
// class returns the classes of one pagination link: the outline button for
// the current page, the ghost button for the others. A zero size is Icon.
func (p PaginationLinkProps) class() string {
size := p.Size
if size == "" {
size = button.Icon
}
if p.Active {
return button.Class(button.Outline, size, p.Class)
}
return button.Class(button.Ghost, size, p.Class)
}
// attrs returns the state attributes of one link, then the caller's.
func (p PaginationLinkProps) attrs() gx.Attrs {
if !p.Active {
return p.Attrs
}
return append(gx.Attrs{{Key: "aria-current", Value: "page"}}, p.Attrs...)
}
// attrs returns the link attributes of the previous link.
func (p PaginationPreviousProps) attrs() gx.Attrs {
return append(gx.Attrs{{Key: "aria-label", Value: "Go to previous page"}}, p.Attrs...)
}
// attrs returns the link attributes of the next link.
func (p PaginationNextProps) attrs() gx.Attrs {
return append(gx.Attrs{{Key: "aria-label", Value: "Go to next page"}}, p.Attrs...)
}package pagination
import "github.com/alternayte/gx"
var PaginationContentFixtures = gx.Fixtures[PaginationContentProps]{"Empty": {}}package pagination
import "github.com/alternayte/gx"
var PaginationEllipsisFixtures = gx.Fixtures[PaginationEllipsisProps]{"Default": {}}package pagination
import "github.com/alternayte/gx"
var PaginationItemFixtures = gx.Fixtures[PaginationItemProps]{"Empty": {}}
// PaginationItemWrap renders the item inside a list, as a page uses it.
func PaginationItemWrap(n gx.Node) gx.Node {
return PaginationContent(PaginationContentProps{Children: n})
}package pagination
import "github.com/alternayte/gx"
var PaginationLinkFixtures = gx.Fixtures[PaginationLinkProps]{
"Inactive": {Href: gx.URL("/?page=2"), Children: gx.Text("2")},
"Active": {Href: gx.URL("/?page=1"), Active: true, Children: gx.Text("1")},
}package pagination
import "github.com/alternayte/gx"
var PaginationNextFixtures = gx.Fixtures[PaginationNextProps]{"Default": {Href: gx.URL("/?page=2")}}package pagination
import "github.com/alternayte/gx"
var PaginationPreviousFixtures = gx.Fixtures[PaginationPreviousProps]{"Default": {Href: gx.URL("/?page=1")}}The theme must define these tokens: --border, --accent, --accent-foreground, --ring.
Usage
<pagination.Pagination>
<pagination.PaginationContent>
<pagination.PaginationItem>
<pagination.PaginationPrevious href={products.List{Page: p.Page - 1}} />
</pagination.PaginationItem>
<pagination.PaginationItem>
<pagination.PaginationLink href={products.List{Page: 1}} active={p.Page == 1}>1</pagination.PaginationLink>
</pagination.PaginationItem>
<pagination.PaginationItem>
<pagination.PaginationNext href={products.List{Page: p.Page + 1}} />
</pagination.PaginationItem>
</pagination.PaginationContent>
</pagination.Pagination>A link has the look of a ghost button. The current page has the look of an outline button.
PaginationPrevious and PaginationNext show a chevron. They hide their text on a narrow screen.
PaginationLink takes a button.Size. The default is button.Icon.
Examples
Pagination: Trail
<pagination.Pagination>
<pagination.PaginationContent>
<pagination.PaginationItem><pagination.PaginationPrevious href={gx.URL("/?page=1")} /></pagination.PaginationItem>
<pagination.PaginationItem>
<pagination.PaginationLink href={gx.URL("/?page=1")} active>1</pagination.PaginationLink>
</pagination.PaginationItem>
<pagination.PaginationItem>
<pagination.PaginationLink href={gx.URL("/?page=2")}>2</pagination.PaginationLink>
</pagination.PaginationItem>
<pagination.PaginationItem><pagination.PaginationEllipsis /></pagination.PaginationItem>
<pagination.PaginationItem><pagination.PaginationNext href={gx.URL("/?page=2")} /></pagination.PaginationItem>
</pagination.PaginationContent>
</pagination.Pagination>PaginationContent: Empty
<pagination.PaginationContent children={gx.Frag()} />PaginationEllipsis: Default
<pagination.PaginationEllipsis />PaginationItem: Empty
<pagination.PaginationItem children={gx.Frag()} />PaginationLink: Inactive
<pagination.PaginationLink href={gx.URL("/?page=2")}>2</pagination.PaginationLink>PaginationLink: Active
<pagination.PaginationLink href={gx.URL("/?page=1")} active>1</pagination.PaginationLink>PaginationNext: Default
<pagination.PaginationNext href={gx.URL("/?page=2")} />PaginationPrevious: Default
<pagination.PaginationPrevious href={gx.URL("/?page=1")} />API reference
A tag sets a prop by its name with a lower-case first letter: Class is class.
pagination.Pagination
| Prop | Type | Default | Description |
|---|---|---|---|
Class |
string |
"" |
Class adds classes to the root element. |
Children |
gx.Node |
Required | Children is the content of the navigation: a PaginationContent. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
pagination.PaginationContent
| Prop | Type | Default | Description |
|---|---|---|---|
Class |
string |
"" |
Class adds classes to the root element. |
Children |
gx.Node |
Required | Children is the pagination items. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
pagination.PaginationEllipsis
| Prop | Type | Default | Description |
|---|---|---|---|
Class |
string |
"" |
Class adds classes to the root element. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
pagination.PaginationItem
| Prop | Type | Default | Description |
|---|---|---|---|
Class |
string |
"" |
Class adds classes to the root element. |
Children |
gx.Node |
Required | Children is the content of the item: a link or an ellipsis. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
pagination.PaginationLink
| Prop | Type | Default | Description |
|---|---|---|---|
Href |
gx.URL |
Required | Href is the URL of the page. |
Active |
bool |
false |
Active marks the link of the current page. It sets aria-current and the outline style. |
Size |
button.Size |
button.Icon |
Size sets the height and padding with a button size. The default is button.Icon, a square link. |
Class |
string |
"" |
Class adds classes to the root element. |
Children |
gx.Node |
Required | Children is the link label, for example the page number. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
pagination.PaginationNext
| Prop | Type | Default | Description |
|---|---|---|---|
Href |
gx.URL |
Required | Href is the URL of the next page. |
Class |
string |
"" |
Class adds classes to the root element. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
pagination.PaginationPrevious
| Prop | Type | Default | Description |
|---|---|---|---|
Href |
gx.URL |
Required | Href is the URL of the previous page. |
Class |
string |
"" |
Class adds classes to the root element. |
Attrs |
gx.Attrs |
nil |
Attrs adds HTML attributes to the root element. |
Do and do not
Do
- Pass typed route values to
Href. - Set
Activeon the current page link.
Don't
- Do not use a pagination link for an action.
- Do not show more links than fit on one line.
Keyboard
| Key | Action |
|---|---|
| Tab | Moves between the links. |
| Enter | Follows the link. |