gooroo

package module
v0.1.10 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2023 License: MIT Imports: 6 Imported by: 0

README

A web frontend library in Go ( WebAssembly )

Dare to imagine web development without JavaScript

Go Reference

Why Gooroo ?

The Gooroo library gathers a set of cumulative functions allowing you to create web applications on the Frontend side. To do this purpose, it implements DOM manipulation features based on syscall/js and webassembly. Its objective is to explore the possibilities of a modern, lightweight and javascript independent web library.

Its functional implementation is based on many React concepts.

Html with variadics - DomComponent

Main App Component

import (
	o "github.com/Matbabs/Gooroo"
)

func App() o.DomComponent {

	return o.Div(
		o.H1("Hello World !"),
		o.Div(
			o.P("This is a paragraph ..."),
			o.Ul(
				o.Li(o.Span("Item 1")),
				o.Li(o.Span("Item 2")),
				o.Li(o.Span("Item 3")),
			),
		),
	)
}

Here you can see the main component of the application. It is a function that returns a DomComponent.

Most of the DomComponents can have a set of children (as in classical HTML), thanks to the variadic parameter passing.

example of DomComponent: o.H1, o.P, o.Span, o.Table, o.Form, o.Input, o.Button ...

Integration with your own components

func App() o.DomComponent {

	p := "This is a prop"

	return o.Div(
		o.H1("Hello World !"),
		o.Div(
			o.P("This is a paragraph ..."),
			component.OtherComponent(p),
		),
	)
}

app.go

func OtherComponent(prop string) o.DomComponent {

	return o.Div(
		o.H1("An other Component !"),
		o.P("This is another paragraph"),
		o.Span(prop),
	)
}

other.go

As in most frontend libraries, Gooroo implements a component system that you can integrate with each other.

Also observe the way in which one or more props can be propagated.

Addition of a CSS style sheet

* {
  color: crimson;
}

master.css

func App() o.DomComponent {

	o.Css("master.css")

	return o.Div(
		o.H1("Hello World !"),
		o.Div(
			o.P("This is a paragraph ..."),
			o.Ul(
				o.Li(o.Span("Item 1")),
				o.Li(o.Span("Item 2")),
				o.Li(o.Span("Item 3")),
			),
		),
	)
}

app.go

You can use o.Css() to integrate your CSS codes.

Conditions & Loops

If - Boolean Condition with o.If

func App() o.DomComponent {

	isTrue := true

	return o.Div(
		o.If(isTrue,
			o.P("This text will be displayed"),
		),
		o.If(!isTrue,
			o.P("This one will be not"),
		),
	)
}

Using the DomElemt o.If allows to define the appearance of the elements if the condition passed in parameter is valid.

For - Loop Condition with o.For

func App() o.DomComponent {

	arr := []string{"Cat", "Dog", "Bird"}

	return o.Div(
		o.For(arr, func(i int) o.DomComponent {
			return o.P(arr[i])
		}),
	)
}

Using the DomElemt o.For allows to define the appearance of the elements of an array using a func(i int) o.DomComponent, where i represents the position of the element in the array.

DomComponent Params

General Params

func App() o.DomComponent {

	return o.Div(o.Style("padding: 40px; color: lightblue"),
		o.H1("Hello World !"),
		o.Div(o.ClassName("container"),
			o.Img(o.Style("height: 150px;"), o.Src("https://go.dev/images/gophers/biplane.svg")),
			o.Div(
				o.A("A link to official Go WebSite", o.Id("go-link"), o.Href("https://go.dev/")),
			),
		),
	)
}

A set of HTML attributes can be hooked through DomComponent.

Here is a non-exhaustive list:

  • o.ClassName
  • o.Style
  • o.Src
  • o.Href
  • o.Value
  • o.Id
  • o.Type
  • o.Placeholder
  • o.Title

Binding Params

func App() o.DomComponent {

	handleClick := func(e js.Value) {
		fmt.Println("Click detected !")
	}

	return o.Div(
		o.Button("Click here", o.OnClick(handleClick)),
	)
}

The DomComponent o.OnClick is a parameter that defines the execution of a callback function func (e js.Value) where e is the JavaScript event.

For example you can use e.Get("type") to recover type of the event.

func App() o.DomComponent {

	var input any

	handleChange := func(e js.Value) {
		// look for
		fmt.Println(e.Get("target").Get("value"))
		// same as
		fmt.Println(input)
	}

	return o.Div(
		o.Input(o.OnChange(&input, handleChange)),
	)
}

The DomComponent o.OnChange is a parameter that defines the execution of a callback function func (e js.Value) where e is the JavaScript event, as well as the update of the value of the pointer passed in parameter.

For example you can use e.Get("target").Get("value") to recover value of the event, but also read pointer input.

Layout Params

Gooroo integrates DomComponent Param responsible for the layout of the elements.

func App() o.DomComponent {

	return o.Div(o.GridLayout(3, 0, "20px"),
		o.Div(
			o.Span("Column 1"),
		),
		o.Div(
			o.Span("Column 2"),
		),
		o.Div(
			o.Span("Column 3"),
		),
	)
}

Use o.GridLauout to define a grid.

func App() o.DomComponent {

	return o.Div(o.FlexLayout("column wrap", "center", "center", "20px"),
		o.Div(
			o.Span("Row 1"),
		),
		o.Div(
			o.Span("Row 2"),
		),
		o.Div(
			o.Span("Row 3"),
		),
	)
}

Use o.FlexLayout to define a flex area.

Use hooks !

UseState - manage the app state

func App() o.DomComponent {

	input, setInput := o.UseState("initial value")

	handleClick := func(e js.Value) {
		setInput(*input)
	}

	return o.Div(
		o.Input(o.OnChange(input)),
		o.Button("Set value", o.OnClick(handleClick)),
		o.P((*input).(string)),
	)
}

o.UseState (as in React.JS) allows to register a variable in the application state.

It returns a pointer to this variable (allowing to access its value) and a setter function.

Once the function is called, the state of the application is updated and the rendering is done again.

UseEffect - control of edge effects

func App() o.DomComponent {

	A, setA := o.UseState("A")
	B, setB := o.UseState("B")

	o.UseEffect(func() {
		fmt.Println("Always !")
	})

	o.UseEffect(func() {
		fmt.Println("When A changed !")
	}, A)

	o.UseEffect(func() {
		fmt.Println("When B changed !")
	}, B)

	o.UseEffect(func() {
		fmt.Println("When A or B changed !")
	}, A, B)

	handleClickA := func(e js.Value) {
		setA(*A)
	}

	handleClickB := func(e js.Value) {
		setB(*B)
	}

	return o.Div(o.GridLayout(2, 0, "20px"),
		o.Input(o.OnChange(A)),
		o.Input(o.OnChange(B)),
		o.Button("Set A", o.OnClick(handleClickA)),
		o.Button("Set B", o.OnClick(handleClickB)),
		o.P((*A).(string)),
		o.P((*B).(string)),
	)
}

o.UseEffect allows to trigger a function when rendering the component.

At each state change and thus new rendering, the o.UseEffect is triggered according to its dependency list:

  • if no state variable, the call is always made
  • if one or more variables, the call is made when one of them changes

UseMemo - optimize expensive calculations

func App() o.DomComponent {

	A, setA := o.UseState("A")

	memoizedValue := o.UseMemo(func() any {
		expensiveCalculation := 1 + 1
		return expensiveCalculation
	}, A)

	handleClickA := func(e js.Value) {
		setA(*A)
	}

	return o.Div(o.GridLayout(2, 0, "20px"),
		o.Input(o.OnChange(A)),
		o.Button("Set A", o.OnClick(handleClickA)),
		o.P((*A).(string)),
		o.P(memoizedValue.(int)),
	)
}

o.UseMemo is used for expensive computations, it allows to return a memoized value. In the same way as o.UseEffect, the calculation is triggered according to its dependency list.

UseCallback - optimize the creation of your lambda functions

func App() o.DomComponent {

	A, setA := o.UseState("A")

	memoizedFunction := o.UseCallback(func(a ...any) any {
		fmt.Println("Memoized function is called !")
		fmt.Println(a[0])
		return a[0]
	}, A)

	handleClickA := func(e js.Value) {
		setA(*A)
	}

	return o.Div(o.GridLayout(2, 0, "20px"),
		o.Input(o.OnChange(A)),
		o.Button("Set A", o.OnClick(handleClickA)),
		o.P((*A).(string)),
		o.P((*memoizedFunction)("It's a parameter").(string)),
	)
}

o.UseCallback is used to avoid regenerating a lambda function, so it returns a pointer to a memoized function. In the same way as o.UseEffect, the regeneration is triggered according to its dependency list.

Install

Get "wasm_exec.js" for Golang Web Assembly

cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

Build Golang Web Assembly Project

GOOS=js GOARCH=wasm go build -o ./main.wasm

Run HTML with Golang Web Assembly

<html>
  <head>
    <title>Example Gooroo</title>
    <link rel="icon" type="image/x-icon" href="./favicon.ico" />
    <meta charset="utf-8" />
    <link rel="stylesheet" href="master.css" />
    <script src="wasm_exec.js"></script>
    <script>
      const go = new Go();
      WebAssembly.instantiateStreaming(
        fetch("main.wasm"),
        go.importObject
      ).then((result) => {
        go.run(result.instance);
      });
    </script>
  </head>
  <body></body>
</html>

Documentation

Overview

The Gooroo package gathers a set of cumulative functions allowing you to create web applications on the Frontend side. To do this purpose, it implements DOM manipulation features based on syscall/js and webassembly. Its objective is to explore the possibilities of a modern, lightweight and javascript independent web library.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Css

func Css(filepath string)

Hangs a CSS file in the <head> content of the website.

func Html

func Html(domComponents ...DomComponent)

Triggers a rendering of the DOM, of all the DomComponents declared in parameters.

func Js added in v0.1.10

func Js(filepath string)

Hangs a Js file in the <head> content of the website.

func Render

func Render(context func())

Starts the library's renderer. Allows to re-trigger the renderings when the state changes (with a UseSate variable for example), through the state channel. Must take a lambda function func() containing the call to Html() as parameter to execute a rendering context.

func UseCallback

func UseCallback(callback func(...any) any, variables ...*any) *func(...any) any

Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed.

func UseEffect

func UseEffect(callback func(), variables ...*any)

Accepts a function that contains imperative, possibly effectful code. The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its variables changes (in variadics params).

func UseMemo

func UseMemo(callback func() any, variables ...*any) any

Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.

func UseState

func UseState(initialValue any) (actualValue *any, f func(setterValue any))

Returns a stateful value, and a function to update it. During the initial render, the returned state (state) is the same as the value passed as the first argument (initialState). The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the DOM.

Types

type DomComponent

type DomComponent func() string

DomComponent represents an element of the DOM. This element can be a tag, an attribute, a layout or even a binding. Most DomComponents can be nested within each other thanks to variadic parameters.

func A

func A[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <a> tag.

func Br

func Br() DomComponent

Declare an html element with the <br> tag.

func Button

func Button[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <button> tag.

func ClassName

func ClassName(className string) DomComponent

Declare an attribute of an html element with the value 'class='

func Div

func Div(insiders ...DomComponent) DomComponent

Declare an html element with the <div> tag.

func FlexLayout

func FlexLayout(flow string, justify string, align string, gap string) DomComponent

Declare une configuration CSS dans l'attribut d'un element html avec la valeur 'style=', de manière a paramettrer un 'display: flex'

func For

func For[T string | int | int32 | int64 | float32 | float64 | bool | any](elements []T, keyDomComponent func(i int) DomComponent) DomComponent

Same operation as htmlDomComponent() but applies the function passed in parameter for the whole array. The "key" element is used to make the link with the elements within the function.

func Form

func Form(insiders ...DomComponent) DomComponent

Declare an html element with the <form> tag.

func GridLayout

func GridLayout[T string | int](columns T, rows T, gap string) DomComponent

Declare une configuration CSS dans l'attribut d'un element html avec la valeur 'style=', de manière a paramettrer un 'display: grid'

func H1

func H1[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <h1> tag.

func H2

func H2[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <h2> tag.

func H3

func H3[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <h3> tag.

func H4

func H4[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <h4> tag.

func Hr added in v0.1.10

func Hr() DomComponent

Declare an html element with the <hr> tag.

func Href

func Href(href string) DomComponent

Declare an attribute of an html element with the value 'href='

func I added in v0.1.10

func I(insiders ...DomComponent) DomComponent

Declare an html element with the <i> tag.

func Id

func Id(id string) DomComponent

Declare an attribute of an html element with the value 'id='

func If

func If(condition bool, insiders ...DomComponent) DomComponent

Same function as htmlDomComponent() but only if the condition in parameter is valid.

func Img

func Img(insiders ...DomComponent) DomComponent

Declare an html element with the <img> tag.

func Input

func Input(insiders ...DomComponent) DomComponent

Declare an html element with the <input> tag.

func Li

func Li(insiders ...DomComponent) DomComponent

Declare an html element with the <li> tag.

func OnChange

func OnChange(value *any, callbacks ...func(js.Value)) DomComponent

Declare a binding on the event 'change' on the attached element to trigger the function passed in parameter.

func OnClick

func OnClick(callbacks ...func(js.Value)) DomComponent

Declare a binding on the event 'click' on the attached element to trigger the function passed in parameter.

func Option

func Option[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <option> tag.

func P

func P[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <p> tag.

func Placeholder

func Placeholder(placeholder string) DomComponent

Declare an attribute of an html element with the value 'placeholder='

func Select

func Select(insiders ...DomComponent) DomComponent

Declare an html element with the <select> tag.

func Span

func Span[T string | int | int32 | int64 | float32 | float64 | bool](text T, insiders ...DomComponent) DomComponent

Declare an html element with the <span> tag.

func Src

func Src(src string) DomComponent

Declare an attribute of an html element with the value 'src='

func Style

func Style(style string) DomComponent

Declare an attribute of an html element with the value 'style='

func Table

func Table(insiders ...DomComponent) DomComponent

Declare an html element with the <table> tag.

func Td

func Td(insiders ...DomComponent) DomComponent

Declare an html element with the <td> tag.

func TextArea

func TextArea(insiders ...DomComponent) DomComponent

Declare an html element with the <textarea> tag.

func Th

func Th(insiders ...DomComponent) DomComponent

Declare an html element with the <th> tag.

func Title

func Title(title string) DomComponent

Declare an attribute of an html element with the value 'title='

func Tr

func Tr(insiders ...DomComponent) DomComponent

Declare an html element with the <tr> tag.

func Type

func Type(_type string) DomComponent

Declare an attribute of an html element with the value 'type='

func Ul

func Ul(insiders ...DomComponent) DomComponent

Declare an html element with the <ul> tag.

func Value

func Value(value string) DomComponent

Declare an attribute of an html element with the value 'value='

Directories

Path Synopsis
It is an HTML, CSS, JS lexer to a set of Go constants.
It is an HTML, CSS, JS lexer to a set of Go constants.
This package describes the private utility and generic functions to the other methods of the main gooroo package.
This package describes the private utility and generic functions to the other methods of the main gooroo package.

Jump to

Keyboard shortcuts

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