Skip to content
Gx
GitHub

Scroll Area

A box with a styled scrollbar.

<scrollarea.ScrollArea class="h-24 w-48 rounded-md border border-border" attrs={gx.Attrs{{Key: "aria-label", Value: "Lines", Kind: gx.AttrText}}}>
  <div class="p-2 text-sm">
    <p>Line one.</p>
    <p>Line two.</p>
    <p>Line three.</p>
    <p>Line four.</p>
    <p>Line five.</p>
    <p>Line six.</p>
    <p>Line seven.</p>
    <p>Line eight.</p>
  </div>
</scrollarea.ScrollArea>

Installation

Run the command in the app module.

Terminal
gx add scroll-area

The command writes these files.

File Path in the app
ScrollArea.gx ui/scroll-area/ScrollArea.gx
ScrollArea.fixtures.go ui/scroll-area/ScrollArea.fixtures.go

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.

ui/scroll-area/ScrollArea.gx
package scrollarea

props {
  // Class adds classes to the root element.
  Class    string = ""
  // Children is the content that scrolls.
  Children gx.Node
  // Attrs adds HTML attributes to the root element.
  Attrs    gx.Attrs = nil
}

<div class={gx.Cx("relative overflow-auto transition-[color,box-shadow] outline-none [scrollbar-color:var(--border)_transparent] [scrollbar-width:thin] focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 motion-reduce:transition-none", p.Class)} tabindex="0" {...p.Attrs}>{p.Children}</div>
ui/scroll-area/ScrollArea.fixtures.go
package scrollarea

import "github.com/alternayte/gx"

// Each line is one paragraph, so the text does not wrap at the scrollbar.
var ScrollAreaFixtures = gx.Fixtures[ScrollAreaProps]{
	"Vertical": {Class: "h-24 w-48 rounded-md border border-border", Attrs: gx.Attrs{{Key: "aria-label", Value: "Lines", Kind: gx.AttrText}}, Children: gx.El("div", gx.Attrs{{Key: "class", Value: "p-2 text-sm", Kind: gx.AttrText}},
		gx.El("p", nil, gx.Text("Line one.")),
		gx.El("p", nil, gx.Text("Line two.")),
		gx.El("p", nil, gx.Text("Line three.")),
		gx.El("p", nil, gx.Text("Line four.")),
		gx.El("p", nil, gx.Text("Line five.")),
		gx.El("p", nil, gx.Text("Line six.")),
		gx.El("p", nil, gx.Text("Line seven.")),
		gx.El("p", nil, gx.Text("Line eight.")),
	)},
	"Horizontal": {Class: "w-48 rounded-md border border-border whitespace-nowrap", Attrs: gx.Attrs{{Key: "aria-label", Value: "One long line", Kind: gx.AttrText}}, Children: gx.El("div", gx.Attrs{{Key: "class", Value: "p-2 text-sm", Kind: gx.AttrText}},
		gx.El("p", nil, gx.Text("One long line that does not wrap and scrolls sideways.")),
	)},
}

The theme must define these tokens: --border, --ring.

Usage

<scrollarea.ScrollArea class="h-64 rounded-md border">
  <div class="p-4">Long content.</div>
</scrollarea.ScrollArea>

The area is a native scroller with a thin scrollbar in the border colour. It scrolls on both axes. The browser draws the scrollbar.

Examples

Vertical

<scrollarea.ScrollArea class="h-24 w-48 rounded-md border border-border" attrs={gx.Attrs{{Key: "aria-label", Value: "Lines", Kind: gx.AttrText}}}>
  <div class="p-2 text-sm">
    <p>Line one.</p>
    <p>Line two.</p>
    <p>Line three.</p>
    <p>Line four.</p>
    <p>Line five.</p>
    <p>Line six.</p>
    <p>Line seven.</p>
    <p>Line eight.</p>
  </div>
</scrollarea.ScrollArea>

Horizontal

<scrollarea.ScrollArea class="w-48 rounded-md border border-border whitespace-nowrap" attrs={gx.Attrs{{Key: "aria-label", Value: "One long line", Kind: gx.AttrText}}}>
  <div class="p-2 text-sm"><p>One long line that does not wrap and scrolls sideways.</p></div>
</scrollarea.ScrollArea>

API reference

A tag sets a prop by its name with a lower-case first letter: Class is class.

scrollarea.ScrollArea

Prop Type Default Description
Class string "" Class adds classes to the root element.
Children gx.Node Required Children is the content that scrolls.
Attrs gx.Attrs nil Attrs adds HTML attributes to the root element.

Do and do not

Do

  • Set a height on the area.
  • Put the padding on the content, not on the area.
  • Keep the scroll on one axis.

Don't

  • Do not nest two scroll areas.
  • Do not use a scroll area for the whole page.

Keyboard

Key Action
Tab Moves focus to the area.
Arrow keys, Page keys Scroll the area when it holds focus.