widget

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package widget is the core of the framework. It defines the interfaces of the widget and provides classes to facilitate their implementation by widget libraries. It also includes the atomic bytes widget, the top-level page widget, the state utility, and the asset registry.

Index

Constants

This section is empty.

Variables

View Source
var AssetRegistry = &assets{}

AssetRegistry is a singleton that keeps all the assets necessary to render widgets. These include CSS (templatized), JavaScript and HTML assets. All widgets must register their assets with the asset registry.

Functions

func IsNil

func IsNil(object any) bool

IsNil checks if the interface is nil or points to nil.

func RandomAlphaNumID

func RandomAlphaNumID(length int) string

RandomAlphaNumID generates a random alphanumeric string of an indicated length. The ID is guaranteed to start with a letter so it is safe to use as an identifier of an HTML element

func SafeHTML

func SafeHTML(unsafeHTML string) (safeHTML string, err error)

SafeHTML parses and rerenders the unsafe HTML to make sure that it is well-formed. It also eliminates scripts and event handlers.

Types

type BytesWidget

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

BytesWidget renders bytes and strings.

func (*BytesWidget) Children

func (wgt *BytesWidget) Children() []Widget

Children are the widgets nested under this widget, or nil if none. Bytes widgets cannot have widgets nested under them.

func (*BytesWidget) Draw

func (wgt *BytesWidget) Draw(w io.Writer, r *http.Request) (err error)

Draw renders the widget's HTML.

func (*BytesWidget) Drawn

func (wgt *BytesWidget) Drawn(r *http.Request) bool

Drawn indicates whether this widget needs to be drawn in either a full or partial page rendering.

func (*BytesWidget) ID

func (wgt *BytesWidget) ID() string

ID is a unique identifier within the scope of the page. Bytes widgets disregard their ID.

func (*BytesWidget) SetID

func (wgt *BytesWidget) SetID(id string)

SetID sets a unique identifier within the scope of the page. Bytes widgets disregard their ID.

func (*BytesWidget) Shown

func (wgt *BytesWidget) Shown(r *http.Request) bool

Shown indicates whether this widget is shown or hidden.

func (*BytesWidget) String

func (wgt *BytesWidget) String() string

String returns the text contained in the widget.

type FileSystem

type FileSystem interface {
	fs.ReadDirFS
	fs.ReadFileFS
}

FileSystem supports reading files and directories.

type InputWidget

type InputWidget interface {
	// Name of the input state variable.
	Name() string

	// Value of the input state variable, given an HTTP request.
	Value(r *http.Request) string

	// Valid indicates if the value is valid, given an HTTP request.
	Valid(r *http.Request) bool

	// Changed indicates if the value posted in an HTTP request differs from the initial value.
	Changed(r *http.Request) bool

	// SetFormName sets the name of the parent form that contains the input widget.
	// This name is used to detect if the form was submitted.
	SetFormName(formName string)
}

InputWidget is a widget that collects input and updates state variables. InputWidgetBase is used to implement this interface.

type InputWidgetBase

type InputWidgetBase[T Widget] struct {
	*WidgetBase[T]
	// contains filtered or unexported fields
}

InputWidgetBase facilitates the implementation of the InputWidget interface.

func NewInputWidgetBase

func NewInputWidgetBase[T Widget](owner T) *InputWidgetBase[T]

NewInputWidgetBase creates a new input widget base holding a pointer to its owner subclass.

func (*InputWidgetBase[T]) AutoSubmit

func (wb *InputWidgetBase[T]) AutoSubmit() bool

AutoSubmit returns a URL that is auto-submitted along with the input's value.

func (*InputWidgetBase[T]) Disabled

func (wb *InputWidgetBase[T]) Disabled() bool

Disabled indicates if the input widget is disabled.

func (*InputWidgetBase[T]) Name

func (wb *InputWidgetBase[T]) Name() string

Name is the name of the state variable affected by this input widget.

func (*InputWidgetBase[T]) Required

func (wb *InputWidgetBase[T]) Required() bool

Required indicates whether the input widget requires a value or not.

func (*InputWidgetBase[T]) SetFormName

func (wb *InputWidgetBase[T]) SetFormName(formName string)

SetFormName sets the name of the parent form that contains the input widget. This name is used to detect if the form was submitted.

func (*InputWidgetBase[T]) Submitted

func (wb *InputWidgetBase[T]) Submitted(r *http.Request) bool

Submitted indicates if the parent form of the input widget was submitted.

func (*InputWidgetBase[T]) WithAutoSubmit

func (wb *InputWidgetBase[T]) WithAutoSubmit(autoSubmit bool) T

WithAutoSubmit sets a URL that is auto-submitted along with the input's value.

func (*InputWidgetBase[T]) WithDisabled

func (wb *InputWidgetBase[T]) WithDisabled(disabled bool) T

WithDisabled sets whether this input widget is enabled or disabled. A disabled widget renders greyed out and its value is not posted back. A widget is enabled by default.

func (*InputWidgetBase[T]) WithName

func (wb *InputWidgetBase[T]) WithName(name string) T

WithName sets the name of the state variable affected by this input widget.

func (*InputWidgetBase[T]) WithRequired

func (wb *InputWidgetBase[T]) WithRequired(required bool) T

WithRequired sets whether the input widget requires a value or not. Values are not required by default.

type NavAreaMarker interface {
	NavAreaMarker()
}

NavAreaMarker marks a widget to render in the navigation area of the page.

type PageTitleMarker

type PageTitleMarker interface {
	PageTitleMarker()
	PageTitle() string
}

PageTitleMarker marks a widget as a provider of the page title.

type PageWidget

type PageWidget struct {
	*WidgetBase[*PageWidget]
	// contains filtered or unexported fields
}

PageWidget renders a top-level HTML page.

func (*PageWidget) Add

func (wgt *PageWidget) Add(children ...any) *PageWidget

Add adds nested widgets.

func (*PageWidget) Children

func (wgt *PageWidget) Children() []Widget

Children are the widgets nested under this widget.

func (*PageWidget) Draw

func (wgt *PageWidget) Draw(w io.Writer, r *http.Request) (err error)

Draw renders the widget's HTML.

func (*PageWidget) WithKeyColors

func (wgt *PageWidget) WithKeyColors(palette css.KeyColors) *PageWidget

WithKeyColors sets the color palette of the page.

func (*PageWidget) WithLang

func (wgt *PageWidget) WithLang(lang string) *PageWidget

WithLang sets the BCP 47 language tag emitted on the <html> element (e.g. "en", "en-US", "fr", "zh-Hans"). Defaults to "en". Screen readers use this to pick a pronunciation dictionary; search engines use it for language-targeting. Empty string suppresses the attribute.

func (*PageWidget) WithTarget

func (wgt *PageWidget) WithTarget(target string) *PageWidget

WithTarget sets a default target for links and forms embedded in the page.

func (*PageWidget) WithThemeDark

func (wgt *PageWidget) WithThemeDark() *PageWidget

WithThemeDark forces the page to be rendered in the dark theme.

func (*PageWidget) WithThemeDefault

func (wgt *PageWidget) WithThemeDefault() *PageWidget

WithThemeDefault renders the page using the browser's theme.

func (*PageWidget) WithThemeLight

func (wgt *PageWidget) WithThemeLight() *PageWidget

WithThemeLight forces the page to be rendered in the light theme.

func (*PageWidget) WithTitle

func (wgt *PageWidget) WithTitle(title string) *PageWidget

WithTitle sets the title of the page. Titles of top-level pages typically show in the browser.

type Resettable

type Resettable interface {
	Reset()
}

Resettable allows resetting the reader of the request body stream.

type State

type State url.Values

State is the collection of the key-value pairs transferred between the frontend and the backend. It is a thin wrapper over the request's form.

func (State) Changed

func (s State) Changed(key string) bool

Changed returns the list of state variables that were reported changed by the frontend.

func (State) Del

func (s State) Del(key string)

Del deletes the value of a state variable.

func (State) Get

func (s State) Get(key string) string

Get returns the value of a state variable or the empty string if not found.

func (State) Has

func (s State) Has(key string) bool

Has indicates if the state variable is found.

func (State) HasChanges

func (s State) HasChanges() bool

HasChanges indicates if the request includes changes to the state. This indicates a partial redrawing request.

func (State) MarshalJSON

func (s State) MarshalJSON() ([]byte, error)

MarshalJSON marshals the state as a JSON map, excluding any variables that begin with an underscore, with the exception of the _back variable that is marshaled.

func (State) Set

func (s State) Set(key string, value string)

Set sets the value of a state variable, replacing any existing values.

type TagWidget

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

TagWidget renders an HTML tag to the page.

func (*TagWidget) Add

func (tag *TagWidget) Add(widgets ...any) *TagWidget

Add nests other widgets inside this tag.

func (*TagWidget) Attr

func (tag *TagWidget) Attr(name string, value string) *TagWidget

Attr adds an attribute to the tag, i.e. <tag name="value">. The attribute is not rendered if the value is empty, except in the case of the "value" attribute.

func (*TagWidget) AttrIf

func (tag *TagWidget) AttrIf(condition bool, name string, value string) *TagWidget

AttrIf sets the attribute only if the condition is met.

func (*TagWidget) Children

func (tag *TagWidget) Children() []Widget

Children are the widgets nested under this widget, or nil if none. Bytes widgets cannot have widgets nested under them.

func (*TagWidget) Class

func (tag *TagWidget) Class(classes ...string) *TagWidget

Class adds to the class attribute of the tag.

func (*TagWidget) ClassIf

func (tag *TagWidget) ClassIf(condition bool, classes ...string) *TagWidget

ClassIf adds to the class attribute only if the condition is met.

func (*TagWidget) Draw

func (tag *TagWidget) Draw(w io.Writer, r *http.Request) (err error)

Draw renders the tag, its attributes, and children to the writer.

func (*TagWidget) Drawn

func (tag *TagWidget) Drawn(r *http.Request) bool

Drawn indicates whether this widget needs to be drawn in either a full or partial page rendering. Tag widgets are always drawn.

func (*TagWidget) Hide

func (tag *TagWidget) Hide(hide bool) *TagWidget

Hide causes the tag not to be displayed, but still rendered.

func (*TagWidget) ID

func (tag *TagWidget) ID() string

ID is a unique identifier within the scope of the page. Tag widgets disregard their ID.

func (*TagWidget) NoEnd

func (tag *TagWidget) NoEnd() *TagWidget

NoEnd indicates not to end the tag with </name>. By default the tag is ended.

func (*TagWidget) SetID

func (tag *TagWidget) SetID(id string)

SetID sets a unique identifier within the scope of the page. Tag widgets disregard their ID.

func (*TagWidget) Shown

func (tag *TagWidget) Shown(r *http.Request) bool

Shown indicates whether this widget is shown or hidden. Tag widgets are always shown.

func (*TagWidget) String

func (tag *TagWidget) String(r *http.Request) string

Render renders the tag, its attributes, and children to a string.

func (*TagWidget) Style

func (tag *TagWidget) Style(styles ...string) *TagWidget

Style adds to the style attribute of the tag.

func (*TagWidget) StyleIf

func (tag *TagWidget) StyleIf(condition bool, styles ...string) *TagWidget

StyleIf adds to the style attribute of the tag only if the condition is met.

func (*TagWidget) When

func (tag *TagWidget) When(flag bool) *TagWidget

When sets a flag that must be satisfied for the tag to be rendered. If the flag is false, an empty placeholder span is rendered instead.

type Widget

type Widget interface {
	// ID is a unique identifier within the scope of the page.
	ID() string

	// SetID sets a unique identifier within the scope of the page.
	SetID(id string)

	// Children are the widgets nested under this widget, or nil if none.
	Children() []Widget

	// Draw renders the widget to the writer, given an HTTP request.
	Draw(w io.Writer, r *http.Request) (err error)

	// Drawn indicates whether this widget needs to be drawn in either a full or partial page rendering.
	Drawn(r *http.Request) bool

	// Shown indicates whether this widget is shown or hidden.
	Shown(r *http.Request) bool
}

Widget is a UI component that is rendered on a page. WidgetBase is used to implement this interface.

type WidgetBase

type WidgetBase[T Widget] struct {
	// contains filtered or unexported fields
}

WidgetBase facilitates the implementation of the Widget interface.

func NewWidgetBase

func NewWidgetBase[T Widget](owner T) *WidgetBase[T]

NewWidgetBase creates a new widget base holding a pointer to its owner subclass.

func (*WidgetBase[T]) Children

func (wb *WidgetBase[T]) Children() []Widget

Children are the widgets nested under this widget. The default implementation returns no children.

func (*WidgetBase[T]) Draw

func (wb *WidgetBase[T]) Draw(w io.Writer, r *http.Request) (err error)

Draw renders the widget's HTML. The default implementation renders an empty placeholder span. Widgets should override this method to render their HTML.

func (*WidgetBase[T]) Drawn

func (wb *WidgetBase[T]) Drawn(r *http.Request) bool

Drawn indicates whether this widget needs to be drawn.

func (*WidgetBase[T]) HideIf

func (wb *WidgetBase[T]) HideIf(condition bool) T

HideIf is used to indicate if the widget needs to be shown or not. Consecutive calls are OR-ed together. It is enough that any condition is true for the widget to be hidden. By default the widget is shown.

func (*WidgetBase[T]) HideIfEmpty

func (wb *WidgetBase[T]) HideIfEmpty(r *http.Request, stateVarName string) T

HideIfEmpty is equivalent to HideIf(StateOf(r).Get(stateVarName)=="").

func (*WidgetBase[T]) HideIfEq

func (wb *WidgetBase[T]) HideIfEq(r *http.Request, stateVarName string, value string) T

HideIfEq is equivalent to Hide(StateOf(r).Get(stateVarName)==value).

func (*WidgetBase[T]) HideIfNotEq

func (wb *WidgetBase[T]) HideIfNotEq(r *http.Request, stateVarName string, value string) T

HideIfNotEq is equivalent to Hide(StateOf(r).Get(stateVarName)!=value).

func (*WidgetBase[T]) ID

func (wb *WidgetBase[T]) ID() string

ID is an identifier of this widget that is unique in the scope of its page.

func (*WidgetBase[T]) RedrawIf

func (wb *WidgetBase[T]) RedrawIf(condition bool) T

RedrawIf forces the redrawing of a widget if the condition is satisfied. Consecutive calls are OR-ed together. It is enough that any condition is true for the widget to be redrawn. By default the widget is drawn only on the initial page drawing. Redrawing a widget may either show or hide it, depending on the status of its shown flag.

func (*WidgetBase[T]) RedrawIfChanged

func (wb *WidgetBase[T]) RedrawIfChanged(r *http.Request, stateVarName ...string) T

RedrawIfChanged is equivalent to multiple RedrawIf(StateOf(r).Changed(stateVarName)).

func (*WidgetBase[T]) RedrawIfChangedTo

func (wb *WidgetBase[T]) RedrawIfChangedTo(r *http.Request, stateVarName string, value string) T

RedrawIfChangedTo is equivalent to RedrawIf(StateOf(r).Changed(stateVarName) && StateOf(r).Get(stateVarName)==value).

func (*WidgetBase[T]) RedrawIfEmpty

func (wb *WidgetBase[T]) RedrawIfEmpty(r *http.Request, stateVarName string) T

RedrawIfEmpty is equivalent to RedrawIf(StateOf(r).Get(stateVarName)=="").

func (*WidgetBase[T]) RedrawIfEq

func (wb *WidgetBase[T]) RedrawIfEq(r *http.Request, stateVarName string, value string) T

RedrawIfEq is equivalent to RedrawIf(StateOf(r).Get(stateVarName)==value).

func (*WidgetBase[T]) RedrawIfNotEq

func (wb *WidgetBase[T]) RedrawIfNotEq(r *http.Request, stateVarName string, value string) T

RedrawIfNotEq is equivalent to RedrawIf(StateOf(r).Get(stateVarName)!=value).

func (*WidgetBase[T]) SetID

func (wb *WidgetBase[T]) SetID(id string)

SetID sets an identifier of this widget that is unique in the scope of its page.

func (*WidgetBase[T]) Shown

func (wb *WidgetBase[T]) Shown(r *http.Request) bool

Shown returns whether the widget is shown or hidden. A widget that is hidden is not rendered.

func (*WidgetBase[T]) WithID

func (wb *WidgetBase[T]) WithID(id string) T

WithID sets an identifier of this widget that is unique in the scope of its page.

type WidgetFactory

type WidgetFactory struct{}

WidgetFactory aggregates the widget constructors of this package. Use WidgetFactory{} to construct a new factory

func (WidgetFactory) Any

func (f WidgetFactory) Any(object any) Widget

Any creates a new widget that best fit the type of the argument. Nils are tolerated. Unrecognized types are formatted into a string by default.

func (WidgetFactory) Bytes

func (f WidgetFactory) Bytes(b []byte) *BytesWidget

Bytes creates a new widget that renders bytes to the page without escaping.

Warning! Use of this type presents a security risk: the content should come from a trusted source, as it will be rendered verbatim.

func (WidgetFactory) Date

func (f WidgetFactory) Date(dateTime time.Time) *BytesWidget

Date creates a new widget that renders a date in the US format "1/2/2006".

func (WidgetFactory) DateOrTime

func (f WidgetFactory) DateOrTime(dateTime time.Time) *BytesWidget

Time creates a new widget that renders a date in the US format "1/2/2006" or time in the US format "3:04:05 PM" if the given time is today.

func (WidgetFactory) DateTime

func (f WidgetFactory) DateTime(dateTime time.Time) *BytesWidget

DateTime creates a new widget that renders a date and time in the US format "1/2/2006 3:04:05 PM".

func (WidgetFactory) Duration

func (f WidgetFactory) Duration(dur time.Duration) *BytesWidget

Duration creates a new widget that renders a duration in the format "2d 1h 0m 1s"

func (WidgetFactory) Float

func (f WidgetFactory) Float(flt float64, precision int) *BytesWidget

Float creates a new widget that renders a float in US format "1,234.5678".

func (WidgetFactory) HTML

func (f WidgetFactory) HTML(html ...string) *BytesWidget

HTML creates a new widget that renders HTML to the page without escaping it. The HTML is parsed and rerendered to make sure that it is well-formed. Scripts and event handlers are eliminated from the HTML.

func (WidgetFactory) HTMLUnsafe

func (f WidgetFactory) HTMLUnsafe(html ...string) *BytesWidget

HTMLUnsafe creates a new widget that renders HTML to the page without escaping it.

Warning! Use of this type presents a security risk: the content should come from a trusted source, as it will be rendered verbatim.

func (WidgetFactory) Integer

func (f WidgetFactory) Integer(i int) *BytesWidget

Integer creates a new widget that renders an integer in US format "1,234".

func (WidgetFactory) Many

func (f WidgetFactory) Many(objects ...any) []Widget

Many creates a collection of widgets that best fit the type of the arguments. Nils are tolerated. Unrecognized types are formatted into a string by default.

func (WidgetFactory) Markdown

func (f WidgetFactory) Markdown(md ...string) *BytesWidget

Markdown creates a new widget that converts markdown to HTML and renders it to the page without escaping it. The HTML is parsed and rerendered to make sure that it is well-formed. Scripts and event handlers are eliminated from the HTML.

func (WidgetFactory) Nbsp added in v0.1.1

func (f WidgetFactory) Nbsp() *BytesWidget

Nbsp creates a new widget that renders a non-breaking space "&nbsp;" to the page.

func (WidgetFactory) Page

func (f WidgetFactory) Page() *PageWidget

Page creates a new widget that renders a top-level HTML page.

func (WidgetFactory) Redirect

func (f WidgetFactory) Redirect(w http.ResponseWriter, r *http.Request, location string)

Redirect writes a 307 redirect to the response.

func (WidgetFactory) RedirectBack

func (f WidgetFactory) RedirectBack(w http.ResponseWriter, r *http.Request) (ok bool)

RedirectBack redirects to the URL in the _back state variable. If a _back variable is not present, it does nothing and returns false.

func (WidgetFactory) StateOf

func (f WidgetFactory) StateOf(r *http.Request) State

StateOf returns the state variables of the HTTP request. The returned State is never nil — if the request body could not be parsed as an HTML form, an empty State is returned so callers can safely Get/Has without a nil check.

func (WidgetFactory) Tag

func (f WidgetFactory) Tag(name string) *TagWidget

Tag creates a new tag writer with the specified <name>. If the tag name is empty, the tag will not render.

func (WidgetFactory) Text

func (f WidgetFactory) Text(str ...string) *BytesWidget

Text creates a new widget that renders a string to the page after escaping it.

func (WidgetFactory) Time

func (f WidgetFactory) Time(dateTime time.Time) *BytesWidget

Time creates a new widget that renders a time in the US format "3:04:05 PM".

func (WidgetFactory) TimeZone

func (f WidgetFactory) TimeZone(loc *time.Location) *BytesWidget

TimeZone creates a new widget that renders a time zone in the format "MST (GMT-0700)".

func (WidgetFactory) Void

func (f WidgetFactory) Void() *BytesWidget

Void creates a new widget that does nothing.

type WriterAssistant

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

WriterAssistant wraps an underlying writer, adding helper functions for writing strings and keeping track of the first error.

func NewWriterAssistant

func NewWriterAssistant(w io.Writer) *WriterAssistant

NewWriterAssistant creates a new assistant for writing to an underlying writer.

func (*WriterAssistant) Err

func (hw *WriterAssistant) Err() error

Err is the first error encountered during a write operation.

func (*WriterAssistant) Write

func (hw *WriterAssistant) Write(b []byte) (int, error)

Write writes bytes to the underlying writer.

func (*WriterAssistant) WriteString

func (hw *WriterAssistant) WriteString(items ...string) (int, error)

WriteString writes one or more strings to the underlying writer.

Jump to

Keyboard shortcuts

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