Skip to content

rfwlab/ui

Repository files navigation

rfw-ui

A minimal, rfw-native UI component library. Components are composition-style builders: each constructor creates real DOM elements and returns a chainable node. Every node exposes Element() dom.Element, so it satisfies composition.Node and can be appended anywhere the rfw composition package accepts nodes. No RTML templates are required.

Styling ships as a single embedded stylesheet driven by CSS custom properties (monochrome by default). The first component you build injects it once; ui.InjectCSS() does it explicitly.

Status

This library is v0: the API is unstable and may change without notice. rfw itself is pre-1.0, so the usual pre-1.0 rfw caveats apply here too.

Install

go get github.com/rfwlab/ui

All DOM-touching code is behind //go:build js && wasm; build your app with GOOS=js GOARCH=wasm.

Quick start

ui.Mount("#app",
    ui.Card().Title("Hello").Text("Built with rfw-ui."),
    ui.Button("Save").Primary().OnClick(func() { /* ... */ }),
)

ui.Mount injects the stylesheet and appends the nodes to the first element matching the selector. Nodes also compose with composition.Bind:

composition.Bind("#app", func(e composition.El) {
    e.Append(ui.Badge("beta").Primary())
})

Components

Button

ui.Button("Save").Primary().OnClick(func() { save() })
ui.Button("Delete").Danger().Small()

Input

Label plus validation state; binds to a state.Signal[string] if you want.

name := ui.Input("Name").Placeholder("Ada Lovelace").OnInput(func(v string) {
    if v == "" {
        name.Invalid("Name is required")
    } else {
        name.Valid()
    }
})

Select

Native <select> wrapper.

ui.Select("Runner").Options("wine", "proton").Value("wine").
    OnChange(func(v string) { setRunner(v) })

Checkbox

ui.Checkbox("Enable DXVK").Checked(true).OnChange(func(on bool) { toggle(on) })

Switch

ui.Switch("Dark mode").On(false).OnChange(func(on bool) { setTheme(on) })

Card

ui.Card().Title("Settings").
    Body(ui.Switch("Telemetry")).
    Footer(ui.Button("Apply").Primary())

Modal

Visibility is driven by a boolean signal; Open/Close are shorthands for setting it.

m := ui.Modal("Confirm").Text("Delete this bottle?").
    Footer(ui.Button("Delete").Danger().OnClick(func() { m.Close() }))
ui.Mount("body", m)
m.Open() // or m.Signal().Set(true)

Tabs

The active index lives in an int signal, available via Active().

ui.Tabs().
    Tab("General", ui.Input("Name")).
    Tab("Advanced", ui.Switch("Experimental"))

Table

Column definitions plus row data.

ui.Table(ui.Column{Title: "Name"}, ui.Column{Title: "Runner", Width: "10rem"}).
    Rows([][]string{{"Photoshop", "wine"}, {"Steam", "proton"}}).
    Striped()

Badge

ui.Badge("beta").Primary()
ui.Badge("failing").Danger()

Spinner

ui.Spinner().Large().Label("Loading bottles")

Notice

A toast-like inline alert.

ui.Notice("Settings saved.").Success().Dismissible()
ui.Notice("Connection lost.").Title("Network").Error()

Tooltip

CSS-only, rendered from a data attribute on hover and focus.

ui.Tooltip("Runs the bottle", ui.Button("Run"))
ui.Tooltip("Shown below", ui.Badge("info")).Bottom()

Theming

All components read from CSS custom properties declared on :root. Override them anywhere in your own stylesheet (on :root, or scoped to a container) to retheme every component at once:

:root {
  --ui-accent: #4f46e5;      /* primary buttons, switches, active tabs */
  --ui-accent-fg: #ffffff;   /* text on accent surfaces */
  --ui-bg: #0f0f0f;          /* control and card background */
  --ui-fg: #ededed;          /* default text */
  --ui-muted: #9a9a9a;       /* secondary text */
  --ui-border: #2c2c2c;      /* borders and dividers */
  --ui-surface: #1a1a1a;     /* subtle fills (hover, table header) */
  --ui-danger: #f87171;
  --ui-success: #4ade80;
  --ui-warning: #facc15;
  --ui-info: #60a5fa;
  --ui-radius: 6px;
  --ui-font: system-ui, sans-serif;
}

The default palette is monochrome: black accent on white, with color reserved for danger, success, warning and info states.

License

GNU Affero General Public License v3.0, the same license as rfw. Copyright (C) Mirko Brombin. See LICENSE.

About

rfw-native UI component library

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors