style

package
v0.6.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package style is the stylesheet engine for visual components.

It is excluded from WebAssembly by `//go:build !wasm` so it can never reach the client binary.

Index

Examples

Constants

View Source
const AutoRotateLayers = 6

AutoRotateLayers is the fixed number of stacked children AutoRotate() choreographs. RenderCSS runs on a zero-value receiver (see the package's zero-value contract), so the rule can never see how many images a real instance holds — it has to commit to a layer count at compile time instead of computing one from instance data. A caller with fewer real images than AutoRotateLayers must cycle through them to fill every slot (Images[i % len(Images)] for i in [0, AutoRotateLayers)); leaving a slot's position empty in the DOM produces a silent gap in the rotation — no image visible — for that slot's turn, because the CSS has no way to know the slot is unused and shrink the cycle around it.

Variables

This section is empty.

Functions

This section is empty.

Types

type Aspect added in v0.4.0

type Aspect uint8

Aspect is the aspect ratio for MediaBox containers.

const (
	AspectSquare Aspect = iota
	Aspect3x2
	Aspect4x3
	Aspect16x9
)

type ColumnWidth added in v0.4.0

type ColumnWidth uint8

ColumnWidth represents minimum column width for grids.

const (
	ColumnNarrow ColumnWidth = iota
	ColumnMedium
	ColumnWide
)

type Edge added in v0.5.0

type Edge uint8

Edge is a block-axis edge of a box.

const (
	EdgeTop Edge = iota
	EdgeBottom
)

type Elevation

type Elevation uint8

Elevation is the shadow elevation scale.

const (
	Flat Elevation = iota
	Raised
	Floating
	Popover
)

type IconSize added in v0.4.4

type IconSize uint8

IconSize is the square size scale for icon-sized parts. The steps are relative to the inherited font size, so an icon tracks the text it sits with.

const (
	IconSm IconSize = iota // inline with a line of text
	IconMd                 // a control's icon: button, field affix
	IconLg                 // a navigation rail or toolbar icon
)

type Motion added in v0.3.1

type Motion uint8

Motion is the transition scale. Duration is owned by CSS; here we only select the level.

const (
	MotionNone Motion = iota // no transition
	MotionFast               // immediate highlight: hover, focus
	MotionBase               // state change
	MotionSlow               // panel/overlay transition
)

type Option added in v0.4.0

type Option func(*rule)

Option is a visual option that configures a rule.

func Anchor added in v0.5.0

func Anchor() Option

Anchor makes the element a positioning reference: it emits position: relative, which is what lets a Flyout descendant hang from it. It is the trigger's container — a menu, a combobox.

Anchor() only wins if nothing positioned sits between it and the Flyout: CSS resolves the Flyout's inset against the nearest POSITIONED ancestor, so a Docked/OnEdge/Backdrop part in between becomes the containing block instead and the Anchor is dead code. Validate() rejects that composition — see Within() for the legal way to declare nesting.

func Animate added in v0.3.1

func Animate(m Motion) Option

Animate applies a transition according to the motion scale.

func As added in v0.4.0

func As(s Surface) Option

As sets the surface decision (background, text, border, and radius default).

func AutoRotate added in v0.6.10

func AutoRotate() Option

AutoRotate stacks up to AutoRotateLayers children as full-bleed layers and cross-fades between them forever, driven purely by a shared @keyframes rule and a per-child animation-delay staggered by DOM position — no state to manage, no JS, no scroller. It is the unattended counterpart of SlideDeck: SlideDeck changes panel because something set widget.Current, AutoRotate changes layer because time passed.

The stagger is expressed as :nth-child selectors, not as a parameter: like every other rule in this package, AutoRotate runs on a zero-value receiver when the stylesheet is built (see the package doc), so it cannot read how many children a real instance renders. It always choreographs exactly AutoRotateLayers slots; a caller with fewer real images must tile them across all slots (see AutoRotateLayers) so no slot's turn goes dark.

prefers-reduced-motion turns the animation off. Every layer then rests at its own plain (non-animated) opacity, which this rule sets to visible only for :first-child — the reduced-motion fallback is "first image, frozen", automatically, with no extra markup from the caller.

func Backdrop added in v0.3.0

func Backdrop(s Scope) Option

Backdrop removes the element from the normal flow and stretches it over its Scope.

Example
package main

import (
	"github.com/tinywasm/widget"
	"github.com/tinywasm/widget/style"
)

type myButton struct{}

func (b *myButton) WidgetName() widget.Name { return widget.Name("btn") }
func (b *myButton) WidgetKind() widget.Kind { return widget.Region }

func main() {
	btn := &myButton{}
	_ = style.For(btn).
		Part("overlay", style.Backdrop(style.Viewport), style.Veil())
}

func Capitalize added in v0.5.11

func Capitalize() Option

Capitalize uppercases the first letter of every word the element renders. It is for text that arrives from a data source in whatever case the source happens to store it — a model's field names becoming a form's labels — so the presentation layer decides the casing instead of every caller having to pre-format the string it passes in.

func Center

func Center(max ...Size) Option

Center defines a centered column with an optional maximum size (defaults to Readable).

func CenterContent added in v0.5.0

func CenterContent() Option

CenterContent centers whatever the element contains, on both axes. A button holding nothing but an icon needs it: the icon is a replaced element with display: block, so the text-align a button carries by default does not move it and it sits against the leading edge.

func CenterSelf added in v0.6.8

func CenterSelf() Option

CenterSelf centers a part horizontally within the space its container gives it, via margin-inline: auto — the counterpart of CenterContent(), which centers what a part CONTAINS rather than the part itself. An item with an explicit width (IconBox(), Width()) inside a wider flex or grid track does not stretch to fill it and defaults to the leading edge; pair it with CenterSelf() to center the fixed-size box inside that track — a calendar day marker inside its week-row column.

func ChipBox added in v0.5.0

func ChipBox() Option

ChipBox gives the element the shared chip width, the box a legend or a badge occupies. Fixing it is what makes a column of chips line up instead of each one hugging its own text; the text itself is truncated by the component that renders it.

func ControlBox added in v0.5.0

func ControlBox() Option

ControlBox gives the element the shared control height, the rhythm every interactive row in the app is measured against — a list row, a form field. Pinning both to one token is what keeps them from drifting apart.

func Cover

func Cover() Option

Cover locks the frame to the viewport height and stacks its children vertically. It is the outermost frame of an application shell: use KeepSize() on the children that must not shrink (a header) and Fill() on the one that takes the remaining height. Do not nest one Cover inside another.

The height is definite, not a floor, so a Fill() descendant resolves against it and a HideOverflow() or Scroll() descendant actually clips. A shell whose content can exceed the viewport must therefore give that descendant Scroll(); otherwise the overflow is unreachable.

func Divider added in v0.6.5

func Divider(side Side) Option

Divider draws a single hairline rule on one inline side — SideEnd for a leading region separated from the content that follows it, SideStart for the mirror case. It is independent of As(): a Surface's border is part of a background+text+border package deal, and a part that wants a plain separator with no background of its own (a badge that no longer fills a color, just marks where it ends) has no Surface to reach for.

func Docked added in v0.5.0

func Docked(scope Scope, edge Edge, side Side, gap Space) Option

Docked pins the element inside a corner, above the content and out of the flow, at the widget kind's stacking layer. Use it for a control that must not cost the content a band of its own: a floating action button, a row's overflow menu.

Parent pins it to the corner of the nearest positioned ancestor — the Anchor only when nothing positioned sits between the two. Viewport pins it to the screen, so it stays put while the content behind it scrolls or swipes — and it disappears with the widget, because a fixed descendant of a display:none ancestor is not rendered either.

Docked also makes the element a containing block: a Flyout inside it hangs from THIS box, not from whatever Anchor sits above. Validate() reports the theft; the fix is either a docked trigger that spans the anchor, or the Flyout moving out of the docked part.

func Drawer added in v0.4.3

func Drawer(side Side, size Size) Option

Drawer anchors the element to one inline edge of the viewport, full height, at the widget kind's stacking layer. It is the slide-in panel of a mobile navigation; pair it with RevealedBy(widget.Open) to control visibility and with a sibling Backdrop(Viewport)+Veil() for the dimmed page behind it.

Drawer sets the element's width. Do NOT also pass Width() — Validate rejects it.

func EdgeStrip added in v0.6.8

func EdgeStrip(scope Scope, side Side) Option

EdgeStrip pins the element to one full inline edge of its Scope — the entire block-axis span (inset-block: 0) plus one inline edge — and, unlike Drawer(), sizes itself to its own content/padding instead of forcing a width, and unlike Docked(), spans the full edge instead of a single corner. Use it for chrome that must stay reachable along an entire edge and is always visible, never toggled: a calendar's full-height prev/next overlay strip. Drawer() is the right primitive instead when the panel is meant to slide in and out — it requires a paired RevealedBy() for exactly that reason; EdgeStrip() has no such requirement because it is not a panel, it is permanent chrome.

Pin it inside an Anchor()ed ancestor for Parent scope, the same relationship Docked() needs.

func EdgeToEdge added in v0.4.0

func EdgeToEdge() Option

EdgeToEdge has no border radius or margin: flush against parent container.

func Fill

func Fill() Option

Fill takes up the entire available height.

func FillCentered added in v0.4.0

func FillCentered() Option

FillCentered fills the container with a centered child.

func FixedGrid added in v0.6.8

func FixedGrid(cols int, gap Space) Option

FixedGrid lays out children in exactly cols equal-width columns; unlike Grid()'s auto-fit/minmax, the column count never reflows on its own. Use Grid() when the item count varies and should reflow with the container's width; use FixedGrid() when the column count is a structural fact — a calendar's 7 weekdays, a fixed-size month strip — and every column must stay equal regardless of content.

cols becomes the --cols custom property, not a literal repeat(N, 1fr): a stylesheet builder must work on a zero-value receiver (it cannot read instance fields), so a column count only known at runtime is set the same way any other per-instance value crosses into an otherwise-static stylesheet — the host overrides --cols inline on the element, never grid-template-columns itself.

func FloatingChrome added in v0.5.12

func FloatingChrome(edge Edge, size IconSize, gap Space) Option

FloatingChrome declares that this element occupies a strip along its edge, and every Scroll() region DESCENDANT of it must reserve that strip — the contract between a floating action button and the scroll container behind it. It emits, on its own box:

--floating-bottom: calc(<size> + 2 * <gap>);

(and the --floating-top counterpart for EdgeTop). The custom property is inherited, so the reservation crosses widget and repository boundaries: the host says "I occupy this band of my edge" and a Scroll() descendant — whatever widget it belongs to — pads itself by var(--floating-bottom, 0px) without either knowing the other's class name. No FloatingChrome means no declaration, and every scroller reserves nothing (the 0px default).

size is IconSize, not Size: floating chrome pinned to a screen edge is by construction a small icon-only control (a FAB, a hamburger) — the same IconBox(...) an author already gave its glyph. Size's members are percentages/keywords meant for a panel's share of a Split or a Flyout's width; a percentage inside padding-block-end resolves against the SCROLL REGION'S OWN inline size, not a fixed footprint, and max-content is not a <length> at all — neither compiles into a calc() that means what this needs. gap is doubled because the same value both pads the control on the edge closest to its icon and sets its own inset off the container edge.

This is the seam the badge-over-FAB overlap needed: the FAB's box is invisible to the badge's scrollHeight, so no padding computed from the badge's own box could reserve the space where the FAB really paints.

func Flyout added in v0.5.0

func Flyout(side Side) Option

Flyout lifts the element out of the flow and hangs it under its containing block, flush with the given inline edge, at the widget kind's stacking layer. Use it for a dropdown: left in the flow, an expanding menu pushes everything below it down and the list jumps under the pointer that opened it.

The containing block is the nearest positioned ancestor. An Anchor() on the chain is what makes it hang where intended — but any positioned part between the two becomes the containing block instead, and nothing in the emitted CSS distinguishes the two. Validate() walks the declared part tree and rejects the interposition; declare the nesting with Within().

func FontSize added in v0.4.0

func FontSize(ts TextSize) Option

FontSize sets the text size.

func FontWeight

func FontWeight(w Weight) Option

FontWeight sets the font weight.

func Foreground added in v0.6.11

func Foreground() Option

Foreground lifts the element above its own widget's Parent-scoped chrome without taking it out of the flow. It is the counterpart of Backdrop(Parent): a backdrop is pinned at the local stacking level (z-index 1, see stackingFor), and an in-flow sibling sits at `auto`, which loses — so a hero banner's caption vanished behind the photograph the moment the photograph actually filled its box. Positioning the content at the SAME level and letting DOM order decide is what puts it back on top; giving it a higher number would outrank a real overlay declared later.

Reach for it only where the widget owns both layers. Between widgets, stacking is the layout's business, not a part's.

func Glyph added in v0.5.0

func Glyph(s Surface) Option

Glyph colours what the element draws — its text and, through currentColor, its icons — with a surface's base colour, and leaves the background alone. It is the "tinted, not filled" treatment: a nav item that is merely available shows a coloured icon, the selected one gets the filled surface via As().

func Grid

func Grid(min ColumnWidth, gap Space) Option

Grid defines auto-fit + minmax without a fixed number of columns.

func Grow added in v0.5.0

func Grow() Option

Grow takes the free space along the inline axis and nothing else. It is the Row counterpart of Fill(): Fill() also claims `height: 100%`, which inside a Row resolves against the row and stretches the part into a full-height block. Use Grow() for the item in a Row that should push its siblings to the trailing edge.

func Hide added in v0.5.0

func Hide() Option

Hide removes the element. Its use is inside On(): a part that exists on wide screens and not on a phone keeps its base styling and is switched off for the one device, which OnlyOn cannot express — OnlyOn hides by default and reveals per device, the opposite direction.

func HideOverflow added in v0.4.0

func HideOverflow() Option

HideOverflow clips descendants (overflow: hidden).

func IconBox added in v0.4.4

func IconBox(s IconSize) Option

IconBox sizes a part as a square that never shrinks — the shape an icon needs. A bare <svg> with no width or height falls back to the replaced-element default of 300x150 and blows the layout apart, so every part that renders one must declare its box here.

func Interactive added in v0.4.0

func Interactive(s Surface) Option

Interactive applies s and derives its hover, focus, and press treatments.

Example
package main

import (
	"github.com/tinywasm/widget"
	"github.com/tinywasm/widget/style"
)

type myButton struct{}

func (b *myButton) WidgetName() widget.Name { return widget.Name("btn") }
func (b *myButton) WidgetKind() widget.Kind { return widget.Region }

func main() {
	btn := &myButton{}
	_ = style.For(btn).
		Root(style.Interactive(style.Primary))
}

func KeepSize added in v0.4.0

func KeepSize() Option

KeepSize does NOT reflow: maintains its size under any width.

func LogoBox added in v0.6.11

func LogoBox() Option

LogoBox caps a media element to the shared control height, width auto to preserve whatever aspect ratio the source art has. A brand mark's file — often an SVG traced from artwork with no relationship to a nav row's geometry — has an intrinsic size the browser will render at verbatim if nothing constrains it, the same failure IconBox exists to prevent for a bare <svg>. IconBox is not the fix here: it forces width equal to height, and a logo is rarely square. ControlBox is not either: min-height sets a floor, not the ceiling an oversized intrinsic image needs.

func MasterDetail added in v0.5.0

func MasterDetail(detail Size) Option

MasterDetail turns a two-panel container into a horizontal scroll-snap strip for a narrow screen: the master list rests where the browser's default scroll position already is, and the detail sits beside it at `detail` of the strip's width, so a sliver of the list stays visible and the panel it came from is obvious. Swiping is a native scroll; snapping to the detail is a plain ScrollIntoView from the row handler.

The FIRST TWO element children are the panels, in the same DOM order a desktop Split uses: detail first, master second. Anything after them — a modal mount point, a portal anchor — is left alone, which is why this addresses them by position and not with :first-child/:last-child. The strip is laid out RTL so the master — the second child, given order 1 — lands at the start edge, which RTL puts on the right, exactly where scroll position 0 already rests. That is what removes the need for a scroll nudge at mount time, which this framework's component contract has no hook for. Each panel resets to LTR so only the outer strip's flow is mirrored, never the content.

func MediaBox added in v0.4.0

func MediaBox(a Aspect) Option

MediaBox defines a box of fixed aspect ratio.

func Meter added in v0.6.8

func Meter(thickness Space) Option

Meter sizes a part as a thin bar whose fill fraction is supplied per instance at runtime — an occupancy indicator, a progress bar. thickness sets the bar's cross-axis size from the space scale; its length axis reads the --meter-fill custom property, which the stylesheet declares the SHAPE of (that it feeds width, and a 0% fallback) but never assigns a value to — a stylesheet builder works on a zero-value receiver, so a per-instance fill level cannot be baked in. The host sets ONLY the value at runtime, e.g. a bare `--meter-fill:73%;` inline style — never a property name, selector, or unit beyond the percent sign the value itself carries.

func OnEdge added in v0.5.0

func OnEdge(edge Edge, side Side, block Space, inline Space) Option

OnEdge centres the element ON one of its Anchor's edge lines — half outside the box, half inside — the way a fieldset legend rides the border it labels.

block is the distance from the Anchor's border to the line being ridden: pass the Anchor's padding to ride the box that padding encloses, or SpaceNone to ride the Anchor's own border. inline is how far the chip is indented along that line. The straddle is exact because the chip's height is the shared --chip-height token, applied as half a chip-height of negative margin.

func Pad

func Pad(s Space) Option

Pad applies internal padding according to the space scale.

func PadEdge added in v0.5.0

func PadEdge(e Edge, s Space) Option

PadEdge pads one block edge only. Pad() is all four sides, which is the right default; this exists for the case where a fixed overlay covers the top of a panel and the content underneath has to start below it without gaining the same inset left and right.

func PadInline added in v0.5.1

func PadInline(s Space) Option

PadInline pads the inline axis (start and end) and nothing else. A chip whose height is contracted against another element — the fieldset legend matches the list badge — cannot take vertical padding, but its text still needs air at the sides; flush text against a filled chip edge reads as a bug, not as density.

func PushEnd added in v0.5.0

func PushEnd() Option

PushEnd sends the part to the trailing edge of its line. It is the companion of Grow(): Grow() absorbs the free space so the items after it are pushed out, PushEnd() moves the free space in front of a single item — the only way to keep something right-aligned once flex-wrap has dropped it onto a line of its own.

func Raise

func Raise(e Elevation) Option

Raise applies shadow elevation according to the elevation scale.

func RevealedBy added in v0.4.0

func RevealedBy(st widget.State) Option

RevealedBy binds hiding/showing the element to a widget State.

Example
package main

import (
	"github.com/tinywasm/widget"
	"github.com/tinywasm/widget/style"
)

type myButton struct{}

func (b *myButton) WidgetName() widget.Name { return widget.Name("btn") }
func (b *myButton) WidgetKind() widget.Kind { return widget.Region }

func main() {
	btn := &myButton{}
	_ = style.For(btn).
		Part("menu", style.RevealedBy(widget.Open))
}

func Round

func Round(rad Radius) Option

Round applies border radius according to the radius scale.

func Row

func Row(gap Space) Option

Row defines a horizontal flow that wraps when it does not fit.

func Scroll added in v0.4.0

func Scroll() Option

Scroll overflows internally instead of growing. Implies Fill().

func ScrollRow added in v0.4.0

func ScrollRow(gap Space) Option

ScrollRow defines a horizontal scrolling strip with scroll-snap and smooth scroll-behavior — so a same-page anchor link (<a href="#childID">) or a programmatic scroll into one of its children slides instead of jumping, with no JS and no per-consumer opt-in.

func Sidebar(side Side, width RailWidth, gap Space) Option

Sidebar places a fixed-width rail beside a fluid content area. The rail keeps its width; the content takes everything else. Below the point where the content can no longer hold its minimum width the two reflow into a single column, with no media query involved.

The container MUST have exactly two element children. Which one is the rail is decided by side, not by DOM order: SideEnd makes the LAST child the rail.

func SlideDeck added in v0.5.3

func SlideDeck(m Motion) Option

SlideDeck apila a sus hijos en capas que ocupan el contenedor entero y muestra solo aquel que lleva el estado widget.Current; los demás quedan aparcados en el borde inline-start y entran deslizándose de izquierda a derecha cuando les toca.

Es la forma de cambiar de panel en un shell SIN crear un scroller: un contenedor de scroll-snap horizontal aquí encadena con el scroll-snap horizontal que un módulo pueda tener adentro, y el gesto de deslizar dentro del contenido termina cambiando de sección sola.

Todos los hijos siguen montados en el DOM. Ese es el trato: el estado decide cuál está en pantalla, nadie desmonta nada. El contenedor es el bloque contenedor de sus hijos, así que un Docked(Parent) dentro de un panel se resuelve contra SU panel — no hace falta Anchor() en el hijo, y ponerlo lo ROMPE: el position: relative de @layer widgets gana sobre el position: absolute que este flujo emite en @layer primitives.

m gobierna la duración del deslizamiento. MotionNone conmuta sin animación.

func Split

func Split(ratio SplitRatio, gap Space) Option

Split defines two panels that stack below their own width.

Example
package main

import (
	"github.com/tinywasm/widget"
	"github.com/tinywasm/widget/style"
)

type myButton struct{}

func (b *myButton) WidgetName() widget.Name { return widget.Name("btn") }
func (b *myButton) WidgetKind() widget.Kind { return widget.Region }

func main() {
	btn := &myButton{}
	_ = style.For(btn).
		Root(style.Split(style.SplitTwoThirds, style.Space3))
}

func Stack

func Stack(gap Space) Option

Stack defines a vertical rhythm with children at full width.

Example
package main

import (
	"github.com/tinywasm/widget"
	"github.com/tinywasm/widget/style"
)

type myButton struct{}

func (b *myButton) WidgetName() widget.Name { return widget.Name("btn") }
func (b *myButton) WidgetKind() widget.Kind { return widget.Region }

func main() {
	btn := &myButton{}
	_ = style.For(btn).
		Root(style.Stack(style.Space4))
}

func StartContent added in v0.5.0

func StartContent() Option

StartContent packs what the element contains against its leading edge. It is the counterpart of CenterContent, for the case where the same part is centred in one state and aligned in another — an icon alone in a narrow rail, icon and label once the rail expands.

func Veil added in v0.4.0

func Veil() Option

Veil fills the element with a translucent wash overlaying the surface. Only makes sense alongside Backdrop.

func Width

func Width(s Size) Option

Width applies the relative width (Size) to the rule.

type Radius

type Radius uint8

Radius is the border radius scale.

const (
	RadiusNone Radius = iota
	RadiusSm
	RadiusMd
	RadiusLg
	RadiusFull
)

type RailWidth added in v0.4.3

type RailWidth uint8

RailWidth is the closed scale for a Sidebar's fixed column.

const (
	RailNarrow RailWidth = iota // icon only
	RailWide                    // icon plus label
)

type Scope added in v0.3.0

type Scope uint8

Scope says what an overlay dimensions against.

const (
	// Parent covers the nearest positioned ancestor (position: absolute).
	Parent Scope = iota
	// Viewport covers the entire window (position: fixed).
	Viewport
)

type Sheet

type Sheet struct {
	// contains filtered or unexported fields
}

Sheet represents a scoped stylesheet for a widget.

func For added in v0.4.0

func For(w widget.Widget) *Sheet

For opens the styling block for a widget.

Example
package main

import (
	"fmt"

	"github.com/tinywasm/widget"
	"github.com/tinywasm/widget/style"
)

type myButton struct{}

func (b *myButton) WidgetName() widget.Name { return widget.Name("btn") }
func (b *myButton) WidgetKind() widget.Kind { return widget.Region }

func main() {
	btn := &myButton{}
	sheet := style.For(btn).
		Root(style.As(style.Primary))

	fmt.Println(sheet.Parts())
}
Output:
[]

func (*Sheet) Cue

func (s *Sheet) Cue(c widget.Cue, p widget.Part, opts ...Option) *Sheet

Cue defines the style for a part (or Root if p is "") when the browser has a cue.

func (*Sheet) CueWithin added in v0.5.0

func (s *Sheet) CueWithin(c widget.Cue, container, p widget.Part, opts ...Option) *Sheet

CueWithin styles a part while an ANCESTOR part carries a browser cue — `.n__container:hover .n__part`. Reach for Cue() first; this is only for the case where the trigger and the thing that reacts are different elements, such as a rail that shows its labels while the pointer is over it.

func (*Sheet) CueWithinHover added in v0.5.8

func (s *Sheet) CueWithinHover(c widget.Cue, container, p widget.Part, opts ...Option) *Sheet

CueWithinHover is CueWithin gated on the fine-pointer capability: the same descendant selector, emitted inside `@media (hover: hover)`. A touch tap fires `:hover` and synthetic mouse events, so a hover reveal that is not scoped this way misfires on a phone — the exact reason this variant exists.

func (*Sheet) On added in v0.4.3

func (s *Sheet) On(d css.Device, p widget.Part, opts ...Option) *Sheet

On defines the style for a part (or Root if p is "") only on the given viewport class. It is the single sanctioned way to vary a widget by device: the query strings live in tinywasm/css and are exhaustively tested there.

Reach for a flow primitive first — Split, Grid and Sidebar already reflow on their own. Use On only when the ARRANGEMENT itself differs, e.g. a nav rail that becomes a drawer.

func (*Sheet) OnlyOn added in v0.4.3

func (s *Sheet) OnlyOn(d css.Device, p widget.Part, opts ...Option) *Sheet

OnlyOn declares a part that exists on one viewport class and nowhere else: it is display:none by default and takes the given options only on d.

Use it for chrome that is genuinely device-specific — a hamburger button, a drawer's backdrop. If the element merely CHANGES between devices rather than disappearing, declare it with Part() and refine it with On().

func (*Sheet) Part

func (s *Sheet) Part(p widget.Part, opts ...Option) *Sheet

Part defines the style for an anatomical part of the widget.

func (*Sheet) Parts added in v0.4.0

func (s *Sheet) Parts() []widget.Part

func (*Sheet) Root

func (s *Sheet) Root(opts ...Option) *Sheet

Root defines the style for the root element of the widget.

func (*Sheet) StateAttrs added in v0.4.3

func (s *Sheet) StateAttrs() []fmt.KeyValue

func (*Sheet) Stylesheet

func (s *Sheet) Stylesheet() *css.Stylesheet

func (*Sheet) Validate added in v0.4.0

func (s *Sheet) Validate() []error

func (*Sheet) When

func (s *Sheet) When(st widget.State, p widget.Part, opts ...Option) *Sheet

When defines the style for a part (or Root if p is "") when the widget has a specific state.

func (*Sheet) WhenWithin added in v0.5.11

func (s *Sheet) WhenWithin(st widget.State, container, p widget.Part, opts ...Option) *Sheet

WhenWithin styles a part while an ANCESTOR part carries a written state — `.n__container[data-x="true"] .n__part`. It is the State counterpart of CueWithin, and like CueWithin it is the exception, not the habit: reach for When() first.

It exists because dom writes a state onto the element that OWNS it, which is not always the element that should change. A form field's read-only gate is written on the field, but what must stop looking editable is the control inside it — When(Locked, PartInput) would emit `.n__input[data-locked="true"]` and match nothing, since the attribute is on the wrapper. Pass "" as container to hang the rule off the widget root.

func (*Sheet) Within added in v0.6.0

func (s *Sheet) Within(container, p widget.Part, opts ...Option) *Sheet

Within declares that part renders INSIDE container, and applies the options to part exactly as Part() would; what it adds is the containment relation, which the sheet needs to reason about positioning — who is whose containing block. It reads like the DOM: Within("menu", "options", Flyout(...)) is "options, inside menu".

Part() remains the normal declaration. Within() is only needed where containment changes the result: a Flyout that hangs from an Anchor while a positioned part sits between them. When it matters, the sheet rejects the composition until the nesting is declared — see Validate().

type Side added in v0.4.3

type Side uint8

Side names which edge a Sidebar's rail or a Drawer's panel is anchored to. Logical, not physical: it follows writing direction.

const (
	SideStart Side = iota // inline-start — left in LTR
	SideEnd               // inline-end   — right in LTR
)

type Size

type Size uint8

Size is the relative size measurement.

const (
	Content  Size = iota // adjusts to its content
	Readable             // readable line length
	Compact              // a single column of controls: a login card, a settings pane
	Third
	Half
	TwoThirds
	Most // 90% — leaves a sliver of what sits behind it
	Full // 100% of the container
)

type Space

type Space uint8

Space is the spacing scale: 8 steps mirroring --space-N.

const (
	SpaceNone Space = iota
	Space1
	Space2
	Space3
	Space4
	Space6
	Space8
	Space12
)

type SplitRatio added in v0.4.0

type SplitRatio uint8

SplitRatio is the flex-grow ratio for Split partitions.

const (
	SplitHalf SplitRatio = iota
	SplitTwoThirds
	SplitThreeQuarters
)

type Surface

type Surface uint8

Surface is a complete visual decision: background, text, and border resolved together.

const (
	Page Surface = iota
	Panel
	Inset
	Primary
	Secondary
	Highlight
	Accent
	AccentWash
	AccentInverse
	AccentHover
	Success
	Danger
	Subtle
	Bare
	Inactive
)

func (Surface) String added in v0.4.0

func (s Surface) String() string

type TextSize

type TextSize uint8

TextSize is the typography size scale.

const (
	TextXs TextSize = iota
	TextSm
	TextBase
	TextLg
	TextXl
	Text2xl
)

type Weight

type Weight uint8

Weight is the font weight scale.

const (
	WeightRegular Weight = iota
	WeightMedium
	WeightBold
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL