ui

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 18 Imported by: 0

README

Ely HTMX

Ely-inspired components for Go html/template, native HTML and htmx. Import a Go module, or export editable templates and assets into your own project. React and a client application framework are not required. CSS, JavaScript and fonts are embedded and served locally; consumers do not need a Node build.

We are deeply grateful to the Ely GPUI project and its contributors. Its visual design, component organization and examples are the foundation of this adaptation. We studied and referenced Ely GPUI Component to bring these ideas to Go, HTML and htmx. This is an independent adaptation, with the original MIT attribution retained. The basic templates also adapt shadcn-htmx.

Install and try

Go 1.26+. In an existing Go module:

go get github.com/mrchypark/ely-htmx@v0.1.0

Run the real form example or the component gallery without cloning:

go run github.com/mrchypark/ely-htmx/examples/app@v0.1.0
# http://127.0.0.1:8092

go run github.com/mrchypark/ely-htmx/examples/gallery@v0.1.0
# http://127.0.0.1:8091/components

The form example demonstrates server validation, an htmx HTML-fragment response, composite controls initialized after a swap, and a full-page fallback when JavaScript is unavailable. It does not store submitted data.

Use in a Go application

Initialize templates and asset routes once, before serving requests:

import ui "github.com/mrchypark/ely-htmx"

templates, err := ui.NewTemplates()
if err != nil { return err }
// Add your own screens before the first ExecuteTemplate call.
if _, err := templates.ParseFS(screenFiles, "templates/*.html"); err != nil { return err }
if err := ui.BindAssets(mux); err != nil { return err }

A screen owns its form action and htmx endpoint:

<link rel="stylesheet" href="/assets/app.css">
{{template "ui-component-assets"}}
<script src="/assets/theme.js"></script>
<script src="/assets/htmx.min.js" defer></script>

<form method="post" action="/profile" hx-post="/profile"
      hx-target="#profile-result" hx-swap="outerHTML">
  <label for="display-name">Name</label>
  {{template "input" (dict "ID" "display-name" "Name" "name" "Required" true)}}
  {{template "button" (dict "Type" "submit" "Label" "Save")}}
</form>
<section id="profile-result" aria-live="polite"></section>

Your handler validates native form values and renders a fragment for HX-Request: true, or a full page otherwise. The library does not register application routes, authorize users, or persist data. BindAssets registers individual GET /assets/... paths. Keep those paths available and do not register another handler for the same exact asset; other application assets can use the /assets/ fallback or their own paths. The current release assumes a root-mounted application and /assets/ URLs.

For catalogue components:

err := ui.RenderComponent(templates, w, ui.Component{
    Chapter: "documents", Name: "MarkdownRenderer", ID: "document-preview",
    Props: map[string]any{"Value": markdown},
})

Include ui-advanced-assets with ui-component-assets, or select CSS with {{template "ui-advanced-family-assets" "workspace"}}. Maps also need ui-map-assets. Give each component a unique ID. Host operations use ely:action / ely:change and the mount API in /assets/ely-api.js; Go handlers own external requests and business rules. See component properties and the seven advanced-*.md guides.

Own and customize the source

Export templates, browser assets, the catalogue and license notices to a new directory:

go run github.com/mrchypark/ely-htmx/cmd/ely@v0.1.0 export -dir ./ely-ui

The export refuses an existing destination so it cannot overwrite your edits. It is a template-and-assets workflow, not a shadcn registry or npx shadcn add implementation. The Go module still supplies rendering helpers for Markdown, QR codes and component resolution.

Override only the templates you need with templates.ParseFS after ui.NewTemplates(), before rendering. Or parse your exported templates into that set. To serve your edited assets, use your own http.FileServer at /assets/ instead of ui.BindAssets:

assets, err := fs.Sub(exportedFiles, "ely-ui/assets")
if err != nil { return err }
mux.Handle("GET /assets/", http.StripPrefix("/assets/", http.FileServer(http.FS(assets))))

Do not convert untrusted strings into template.HTML. Normal properties and validated Attrs remain escaped. The Markdown helper disables raw HTML and unsafe URL schemes.

Themes

Three presets: Blue, Dusty Violet, Oxide Terracotta. Each defines 19 color roles in both light and dark modes. Component aliases derive from those roles. /components/themes provides neutral light/dark previews, editing, contrast checks and JSON import/export.

const theme = ElyTheme.get('violet');
theme.id = 'my-theme';
theme.name = 'My theme';
ElyTheme.register(theme);
ElyTheme.apply(theme.id);

Theme editor with neutral light and dark previews

Theme API documents validation and browser storage. Account synchronization belongs to the host application.

Scope of v0.1.0

The catalogue has 44 chapters, 624 primary stories, 1,279 distinct names and 1,313 chapter-qualified names. Related names can share one renderer; these counts are not independent full engines. The public API takes caller data; gallery fixtures remain in internal/gallery.

Native forms, keyboard handling, local editor interactions, tables, Markdown, QR/barcodes, map selection and host action payloads are included. AI generation, financial execution, authentication, uploads, collaboration and OS/file operations require a host service. Complex charts remain basic presentations; detailed chart work is deferred. GPUI runtime/API compatibility and complete pixel parity are not claimed. Original photos and other unverified copied media are replaced with original synthetic fixtures.

Develop and verify

go test ./...
go vet ./...
npm ci
npm test
npm run build:css
go run ./examples/gallery

Node and Tailwind are needed only to rebuild CSS or run JavaScript unit checks. Open /components/usage for forms and /components/audit?aliases=1 for the browser behavior harness. Click the run button to check all chapter-qualified names with synthetic data and independent instances. This harness checks local behavior and host request contracts, not live external services. Optional media fixture regeneration: python3 scripts/fixtures.py (FFmpeg required).

License and acknowledgements

Project code is MIT. Retain the project license and third-party notices when copying sources. Ely GPUI and shadcn-htmx notices, font OFL licenses, htmx 0BSD, Tailwind/Lottie MIT and Natural Earth provenance remain included.

Documentation

Overview

Package ui provides shared Go templates, theme styles, and browser assets.

Index

Constants

This section is empty.

Variables

View Source
var Files embed.FS

Functions

func BindAssets

func BindAssets(mux *http.ServeMux) error

BindAssets registers shared asset paths without taking over application assets.

func Funcs

func Funcs() template.FuncMap

func NewTemplates

func NewTemplates() (*template.Template, error)

func RenderComponent

func RenderComponent(tpl *template.Template, w io.Writer, component Component) error

RenderComponent renders caller data through a shared, catalogue-resolved API. Use a template set from NewTemplates, including application overrides if needed.

Types

type Component

type Component struct {
	Chapter string
	Name    string
	ID      string
	Props   map[string]any
}

Component is an instance of a catalogue component. Props contain caller data. Chapter disambiguates names such as DocumentViewer used in multiple chapters.

type ComponentChapter

type ComponentChapter struct {
	Number  int              `json:"number"`
	Slug    string           `json:"slug"`
	Title   string           `json:"title"`
	Summary string           `json:"summary"`
	Stories []ComponentStory `json:"stories"`
}

func Catalogue

func Catalogue() ([]ComponentChapter, error)

Catalogue returns a fresh copy of the shared Ely catalogue.

type ComponentDefinition

type ComponentDefinition struct {
	Chapter, Name, Family, Template string
	Aliases                         []string
}

func ComponentDefinitions

func ComponentDefinitions() ([]ComponentDefinition, error)

ComponentDefinitions returns a copy of all primary API definitions.

func ResolveComponent

func ResolveComponent(chapter, name string) (ComponentDefinition, error)

type ComponentStory

type ComponentStory struct {
	Title      string   `json:"title"`
	Name       string   `json:"name"`
	Slug       string   `json:"slug"`
	Components []string `json:"components"`
	Endpoint   string   `json:"-"`
}

ComponentStory identifies an Ely visual recipe and its documented aliases. Aliases are names from Ely's catalogue, not independent implementations.

type Option

type Option struct {
	Value    string
	Label    string
	Selected bool
	Disabled bool
}

Option is a value and label for shared choice controls.

Directories

Path Synopsis
cmd
ely command
Command ely exports editable templates and browser assets.
Command ely exports editable templates and browser assets.
examples
app command
Command app runs a small Ely HTMX form example.
Command app runs a small Ely HTMX form example.
gallery command
Command components serves the standalone Ely HTMX UI example gallery.
Command components serves the standalone Ely HTMX UI example gallery.
internal
gallery
Package uiexamples serves the standalone Ely HTMX UI example gallery.
Package uiexamples serves the standalone Ely HTMX UI example gallery.

Jump to

Keyboard shortcuts

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