app

package module
v0.0.0-...-6bbd6df Latest Latest
Warning

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

Go to latest
Published: May 8, 2019 License: MIT Imports: 18 Imported by: 0

README

ui demo

app

Circle CI Go build Go Report Card GoDoc Custom badge

A WebAssembly framework to build GUI with Go, HTML and CSS.

Install

# Package sources:
go get -u -v github.com/maxence-charriere/app

# Goapp cli tool:
go get -u -v github.com/maxence-charriere/app/cmd/goapp

How it works

Project layout
root
├── cmd
│   ├── demo-server
│   │   └── main.go
│   └── demo-wasm
│       └── main.go
└── web
    ├── wasm_exec.js
    ├── style sheets...
    ├── images...
    └── etc...

This layout follows the project layout defined in golang-standards/project-layout:

  • The cmd directory contains the project main applications.
  • The demo directory contains the app that is compiled in wasm and that will run in the browser.
  • The demo-server directory contains the server that serves the wasm app and its resources.
  • The web directory contrains the app resources like style sheets (css), images and other static resources.

Project layout can be initialized by running this command in the repository root.

goapp init -v
App

The app is the Go code compiled in web assembly and executed in the browser.

// root/cmd/demo-wasm/main.go

package main

import (
    "log"

    "github.com/maxence-charriere/app"
)

type Hello struct {
    Name string
}

func (h *Hello) Render() string {
    return `
<div class="Hello">
    <h1>
        Hello
        {{if .Name}}
            {{.Name}}
        {{else}}
            world
        {{end}}!
    </h1>
    <input value="{{.Name}}" placeholder="What is your name?" onchange="{{bind "Name"}}" autofocus>
</div>
    `
}

func main() {
    app.Import(&Hello{})

    app.DefaultPath = "/hello"

    if err := app.Run(); err != nil {
        log.Print(err)
    }
}
Server

The server serves the web assembly Go program and the other resources.

// root/cmd/demo-server/main.go

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"

    "github.com/maxence-charriere/app"
)

func main() {
    http.Handle("/", &app.Handler{})

    if err := http.ListenAndServe(":3000", nil); err != nil {
        log.Fatal(err)
    }
}
Build

The whole project is built with the goapp CLI tool. Goapp builds the server, the wasm app, imports the required javascript support file and puts the pieces together to provide a ready to use project.

# Get the goapp CLI tool:
go get -u github.com/maxence-charriere/app/cmd/goapp

# Builds a server ready to serve the wasm app and its resources:
goapp build -v

# Launches the server and app in the default browser:
goapp run -v -b default

Once built, the directory tree should look like:

root
├── cmd
│   ├── demo-server
│   │   └── main.go
│   └── demo-wasm
│       └── main.go
├── demo-server (server)
└── web
    ├── goapp.wasm (app)
    ├── wasm_exec.js
    ├── style sheets...
    ├── images...
    └── etc...

See the full example code and the online demo.

Support

Requires Go 1.12.

Platform Chrome Edge Firefox Safari
Desktop
Mobile

Issues:

Documentation

Overview

Package app is a package to build GUI apps with Go, HTML and CSS.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCompoNotMounted describes an error that reports whether a component
	// is mounted.
	ErrCompoNotMounted = errors.New("component not mounted")

	// ErrElemNotSet describes an error that reports if an element is set.
	ErrElemNotSet = errors.New("element not set")

	// ErrNotSupported describes an error that occurs when an unsupported
	// feature is used.
	ErrNotSupported = errors.New("not supported")

	// ErrNoWasm describes an error that occurs when Run or Render are called
	// in a non wasm environment.
	ErrNoWasm = errors.New("go architecture is not wasm")

	// DefaultPath is the path to the component to be  loaded when no path is
	// specified.
	DefaultPath string

	// NotFoundPath is the path to the component to be  loaded when an non
	// imported component is requested.
	NotFoundPath = "/app.notfound"

	// Logger is a function that formats using the default formats for its
	// operands and logs the resulting string.
	// It is used by Log, Logf, Panic and Panicf to generate logs.
	Logger = log.Printf
)

Functions

func Emit

func Emit(e Event, args ...interface{})

Emit emits the event with the given arguments.

func EnableDebug

func EnableDebug(v bool)

EnableDebug is a function that set whether debug mode is enabled.

func Handle

func Handle(key string, h MsgHandler)

Handle handles the message for the given key.

func Import

func Import(c ...Compo)

Import imports the given components into the app. Components must be imported in order the be used by the app package. This allows components to be created dynamically when they are found into markup.

func Log

func Log(a ...interface{})

Log formats using the default formats for its operands and logs the resulting string. Spaces are always added between operands and a newline is appended.

func Logf

func Logf(format string, a ...interface{})

Logf formats according to a format specifier and logs the resulting string.

func Navigate(url string)

Navigate navigates to the given URL.

func NewContextMenu

func NewContextMenu(items ...MenuItem)

NewContextMenu displays a context menu filled with the given menu items.

Context menu requires an app.contextmenu component in the loaded page.

func (c *Compo) Render() string {
	return `
<div>
	<!-- ... -->
	<app.contextmenu>
</div>
	`
}

func Panic

func Panic(a ...interface{})

Panic is equivalent to Log() followed by a call to panic().

func Panicf

func Panicf(format string, a ...interface{})

Panicf is equivalent to Logf() followed by a call to panic().

func Path

func Path(c Compo) string

Path returns the path to the given component.

func Post

func Post(msgs ...Msg)

Post posts the given messages. Messages are handled in another goroutine.

func Reload

func Reload()

Reload reloads the current page.

func Render

func Render(c Compo)

Render renders the given component. It should be called whenever a component is modified.

It panics if called before Run.

func Run

func Run() error

Run runs the app with the loaded URL.

func UI

func UI(f func())

UI calls a function on the UI goroutine.

func WhenDebug

func WhenDebug(f func())

WhenDebug execute the given function when debug mode is enabled.

Types

type Compo

type Compo interface {
	// Render must return HTML 5.
	// It supports standard Go html/template API.
	// The pipeline is based on the component struct.
	// See https://golang.org/pkg/text/template and
	// https://golang.org/pkg/html/template for template usage.
	Render() string
}

Compo is the interface that describes a component. Must be implemented on a non empty struct pointer.

type CompoWithExtendedRender

type CompoWithExtendedRender interface {
	Compo

	// Funcs returns a map of funcs to use when rendering a component.
	// Funcs named raw, json and time are reserved.
	// They handle raw html code, json conversions and time format.
	// They can't be overloaded.
	// See https://golang.org/pkg/text/template/#Template.Funcs for more details.
	Funcs() map[string]interface{}
}

CompoWithExtendedRender is the interface that wraps Funcs method.

type Dismounter

type Dismounter interface {
	Compo

	// OnDismount is called when a component is dismounted.
	// App.Render should not be called inside.
	OnDismount()
}

Dismounter is the interface that wraps OnDismount method.

type DragAndDropArg

type DragAndDropArg struct {
	Files         []string
	Data          string
	DropEffect    string
	EffectAllowed string
	Node          NodeArg
}

DragAndDropArg represents an ondrop event arg.

type Event

type Event string

Event is a string that identifies an app event.

type EventSubscriber

type EventSubscriber interface {
	// Subscribe is called when a component is mounted.
	// The returned subscriber is used to subscribe to events emitted from
	// messages.
	// All the event subscribed are automatically unsuscribed when the component
	// is dismounted.
	Subscribe() *Subscriber
}

EventSubscriber is the interface that describes a component that subscribes to events emitted from messages.

type Handler

type Handler struct {
	http.Handler

	// The app author.
	Author string

	// The app description.
	Description string

	// The app keywords.
	Keywords []string

	// The text displayed while loading a page.
	LoadingLabel string

	// The app name.
	Name string

	// The progressive app mode configuration.
	ProgressiveApp ProgressiveAppConfig

	// The he path of the web directory. Default is web.
	WebDir string
	// contains filtered or unexported fields
}

Handler is a http handler that serves UI components created with this package.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type KeyboardArg

type KeyboardArg struct {
	CharCode  rune
	KeyCode   int
	Location  int
	AltKey    bool
	CtrlKey   bool
	MetaKey   bool
	ShiftKey  bool
	InnerText string
	Node      NodeArg
}

KeyboardArg represents an onkey event arg.

type MenuItem struct {
	Disabled  bool
	Keys      string
	Icon      string
	Label     string
	OnClick   func()
	Separator bool
}

MenuItem represents a menu item.

type Mounter

type Mounter interface {
	Compo

	// OnMount is called when a component is mounted.
	// App.Render should not be called inside.
	OnMount()
}

Mounter is the interface that wraps OnMount method.

type MouseArg

type MouseArg struct {
	ClientX   float64
	ClientY   float64
	PageX     float64
	PageY     float64
	ScreenX   float64
	ScreenY   float64
	Button    int
	Detail    int
	AltKey    bool
	CtrlKey   bool
	MetaKey   bool
	ShiftKey  bool
	InnerText string
	Node      NodeArg
}

MouseArg represents an onmouse event arg.

type Msg

type Msg interface {
	// The message key.
	Key() string

	// The message value.
	Value() interface{}

	// Sets the message value.
	WithValue(interface{}) Msg

	// Posts the message.
	// It will be handled in another goroutine.
	Post()
}

Msg is the interface that describes message.

func NewMsg

func NewMsg(key string) Msg

NewMsg creates a message.

type MsgHandler

type MsgHandler func(Msg)

MsgHandler is the interface that describes a message handler. It is used to respond to a Msg.

type Navigable interface {
	Compo

	// OnNavigate is called when a component is navigated to.
	OnNavigate(u *url.URL)
}

Navigable is the interface that wraps OnNavigate method.

type NodeArg

type NodeArg struct {
	GoappID string
	CompoID string
	ID      string
	Class   string
	Data    map[string]string
	Value   string
}

NodeArg represents a descriptor to an event source.

type NotFound

type NotFound ZeroCompo

NotFound is a component that displays a not found page.

func (*NotFound) Render

func (n *NotFound) Render() string

Render returns the markup that describes the page.

type ProgressiveAppConfig

type ProgressiveAppConfig struct {
	// Enforces landscape mode.
	LanscapeMode bool

	// Provides a short human-readable name for the application. This is
	// intended for when there is insufficient space to display the full name of
	// the web application, like device homescreens.
	//
	// Default is the app name where space are replaces by '-'.
	ShortName string

	// Defines the navigation scope of this website's context. This restricts
	// what web pages can be viewed while the manifest is applied. If the user
	// navigates outside the scope, it returns to a normal web page inside a
	// browser tab/window.
	//
	// Default is "/".
	Scope string

	// The URL that loads when a user launches the application (e.g. when added
	// to home screen), typically the index.
	// Default is "/".
	StartURL string

	// Defines the default theme color for an application. This sometimes
	// affects how the OS displays the site (e.g., on Android's task switcher,
	// the theme color surrounds the site).
	ThemeColor string
}

ProgressiveAppConfig represents the configuration used to describe a progressive app.

type Subscriber

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

Subscriber is a struct to subscribe to events emitted by a event registry.

func NewSubscriber

func NewSubscriber() *Subscriber

NewSubscriber creates an event subscriber to return when implementing the app.EventSubscriber interface.

func (*Subscriber) Close

func (s *Subscriber) Close()

Close unsubscribes all the subscriptions.

func (*Subscriber) Subscribe

func (s *Subscriber) Subscribe(e Event, f interface{}) *Subscriber

Subscribe subscribes a function to the given event. Emit fails if the subscribed func have more arguments than the emitted event.

Panics if f is not a func.

type WheelArg

type WheelArg struct {
	DeltaX    float64
	DeltaY    float64
	DeltaZ    float64
	DeltaMode int
	Node      NodeArg
}

WheelArg represents an onwheel event arg.

type ZeroCompo

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

ZeroCompo is the type to use as base for empty components. Every instances of an empty struct is given the same memory address, which causes problem for indexing components. ZeroCompo have a placeholder field to avoid that.

Directories

Path Synopsis
cmd
demo
internal

Jump to

Keyboard shortcuts

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