dovetail

package module
v0.0.0-...-b6e8aaf Latest Latest
Warning

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

Go to latest
Published: Feb 11, 2021 License: MIT Imports: 6 Imported by: 0

README

Dovetail

CURRENTLY IN ALPHA, API WILL CHANGE

Documentation

User- and developer-friendly HTML Components for Go, inspired by SwiftUI/React/Elm.

  • Produce accessible HTML markup easily.
  • Make components with functions.
  • Supports ARIA and data attributes.
  • Conveniences for forms and lists.
Render(
  w,
  Div(
    Header(
      Nav(
        AriaLabel("Primary"),
        List(
          Link("/", Text("Home")),
          Link("/about", Text("About")),
          Link("/pricing", Text("Pricing"), AriaCurrentPage),
          Link("/sign-in", Text("Sign In")),
          Link("/join", Text("Join")),
        ),
      ),
    ),
    Main(
      Article(
        H(1, Text("Welcome")),
        P("Render HTML using components with Go"),
      ),
      FormTo("/newsletter").With(
        FieldLabelled("Email", Textbox("email")),
        SubmitButton(Text("Sign up for the newsletter")),
      ),
    ),
  )
)

Provided components

Type: HTMLElementView

Landmarks
  • Main(children ...HTMLView)<main>
  • Nav(children ...HTMLView)<nav>
  • Header(children ...HTMLView)<header>
  • Footer(children ...HTMLView)<footer>
  • Section(children ...HTMLView)<section>
  • Article(children ...HTMLView)<article>
  • Aside(children ...HTMLView)<aside>
Structure
  • Div(children ...HTMLView)<div>
  • List(children ...HTMLView)<ul><li>{ children[0] }</li>…<li>{ children[n] }</li></ul>
  • Ul(children ...HTMLView)<ul>
  • Li(children ...HTMLView)<li>
  • Coming soon: <ol>, <dl>
Elements
  • Link(url string, children ...HTMLView)<a href="{ url }">{ children }</a>
  • Button(children ...HTMLView)<button type="button">{ children }</button>
  • Img(srcUrl string, alt string, enhancers ...HTMLEnhancer)<img src="{ srcUrl }" alt="{ alt }" {...enhancers}>
  • P(children ...HTMLView)<p>
  • TextWith(text string, enhancers ...HTMLEnhancer)<span {...enhancers}>{ text }</span>
  • Noscript(children ...HTMLView)<noscript>{ children }</noscript>
Forms
Text nodes
Logic
  • When(when bool, view HTMLView) — renders the provided view only if when is true
Custom
  • HTMLElementViewOf(tagName string, tagAtom atom.Atom, children []HTMLView) — custom html element

Attributes

Define components

Components are defined using functions. These functions can take any number of arguments, and return a composite of other components.

func PrimaryButton(text string) View {
	return Button(Text(text)).Class("btn btn-primary")
}

Performance

While not trying to be the fastest HTML producer possible, Dovetail aims to be faster than html/template to parse and execute.

Run make test_bench to see how Dovetail performs to produce a variety of HTML components. Here are results on a 2016 15″ MacBook Pro:

go test -p 1 -timeout 30s -bench="Bench" -benchmem -v -run "Bench" ./...
goos: darwin
goarch: amd64
pkg: github.com/RoyalIcing/dovetail
BenchmarkTailwindJustDiv-8                  	 4758601	       247 ns/op	     272 B/op	       2 allocs/op
BenchmarkTailwind0Classes-8                 	 4620313	       249 ns/op	     272 B/op	       2 allocs/op
BenchmarkTailwind2Classes-8                 	 2074034	       580 ns/op	     400 B/op	       6 allocs/op
BenchmarkTailwind4Classes-8                 	 1713938	       694 ns/op	     464 B/op	       7 allocs/op
BenchmarkTailwind8Classes-8                 	 1349778	       887 ns/op	     640 B/op	       8 allocs/op
BenchmarkTailwindAddClasses2Classes-8       	 1990402	       601 ns/op	     416 B/op	       6 allocs/op
BenchmarkTailwindAddClasses4Classes-8       	 1771840	       677 ns/op	     480 B/op	       6 allocs/op
BenchmarkTailwindAddClasses8Classes-8       	 1504893	       783 ns/op	     656 B/op	       6 allocs/op
BenchmarkTailwindDivWithClasses8Classes-8   	 1757682	       729 ns/op	     528 B/op	       5 allocs/op
BenchmarkTailwindChangeClasses2Classes-8    	 1797513	       643 ns/op	     464 B/op	       8 allocs/op
BenchmarkTailwindChangeClasses4Classes-8    	 1533936	       790 ns/op	     560 B/op	       9 allocs/op
BenchmarkTailwindChangeClasses8Classes-8    	 1234028	       970 ns/op	     800 B/op	      10 allocs/op
BenchmarkText-8                             	 7639869	       154 ns/op	     128 B/op	       2 allocs/op
BenchmarkHeader-8                           	 4320638	       251 ns/op	     272 B/op	       2 allocs/op
BenchmarkDiv-8                              	 4858587	       242 ns/op	     272 B/op	       2 allocs/op
BenchmarkDivWithClasses1-8                  	 2697412	       445 ns/op	     336 B/op	       4 allocs/op
BenchmarkDivWithClasses2Together-8          	 2296304	       519 ns/op	     368 B/op	       5 allocs/op
BenchmarkDivWithClasses2-8                  	 2066386	       576 ns/op	     384 B/op	       6 allocs/op
BenchmarkDivWithChildClassNames-8           	 1734169	       672 ns/op	     448 B/op	       9 allocs/op
BenchmarkButton-8                           	 2446404	       478 ns/op	     352 B/op	       5 allocs/op
BenchmarkButtonSubmit-8                     	 2451301	       480 ns/op	     352 B/op	       5 allocs/op
BenchmarkH1-8                               	 2267946	       521 ns/op	     448 B/op	       6 allocs/op
PASS
ok  	github.com/RoyalIcing/dovetail	39.216s

Why?

Because I want to create server-rendered web apps that I can host cheaply on GCP App Engine Standard.

I want something that is both user friendly (quick to load, accessible) while also being developer friendly.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AriaCurrentPage = HTMLAttrView{Key: "aria-current", Value: "page"}
View Source
var FocusViaScript = HTMLAttrView{Key: "tabindex", Value: "-1"}

FocusViaScript allows a script to focus this element. It sets the tabindex to -1

View Source
var FocusViaTab = HTMLAttrView{Key: "tabindex", Value: "0"}

FocusViaTab allows the user to focus this element with the tab key. It sets the tabindex to 0

Functions

func Build

func Build(view HTMLView) *html.Node

Build takes an HTMLView and creates an html.Node

func Render

func Render(w io.Writer, views ...HTMLView)

Render takes an HTMLView and renders it and its tree to w

func SpecialButton

func SpecialButton(options ...func(input ButtonView) ButtonView) func(children ...HTMLView) ButtonView

Types

type ButtonView

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

ButtonView makes <button>

func ButtonOld

func ButtonOld(children ...HTMLView) ButtonView

func ButtonSubmit

func ButtonSubmit(input ButtonView) ButtonView

func (ButtonView) Submit

func (button ButtonView) Submit() ButtonView

type ClassNames

type ClassNames []string

ClassNames is a slice of class names

func TailwindToClass

func TailwindToClass(additions ...TailwindClassName) ClassNames

func (ClassNames) Class

func (classNames ClassNames) Class(additions ...string) ClassNames

Class adds the passed class names

func (ClassNames) Concat

func (classNames ClassNames) Concat(additions ClassNames) ClassNames

Concat adds all the class names from another instance

func (ClassNames) Md

func (classNames ClassNames) Md(additions ...TailwindClassName) ClassNames

func (ClassNames) String

func (classNames ClassNames) String() string

Strings converts the class names to a single, space-separated string

func (ClassNames) Tailwind

func (classNames ClassNames) Tailwind(additions ...TailwindClassName) ClassNames

type ClassNamesChanger

type ClassNamesChanger func(classNames ClassNames) ClassNames

func TailwindChanger

func TailwindChanger(additions ...TailwindClassName) ClassNamesChanger

func (ClassNamesChanger) Md

func (changer ClassNamesChanger) Md(additions ...TailwindClassName) ClassNamesChanger

func (ClassNamesChanger) Tailwind

func (changer ClassNamesChanger) Tailwind(additions ...TailwindClassName) ClassNamesChanger

type FieldFileInputOption

type FieldFileInputOption func(FieldHTMLView) FieldHTMLView

func FileInput

func FileInput(inputName string, options ...FieldFileInputOption) FieldFileInputOption

func (FieldFileInputOption) Use

func (option FieldFileInputOption) Use(enhancers ...HTMLEnhancer) FieldFileInputOption

type FieldHTMLView

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

func FieldLabelled

func FieldLabelled(labelText string, option FieldOption, children ...HTMLEnhancer) FieldHTMLView

func (FieldHTMLView) Class

func (field FieldHTMLView) Class(className string) FieldHTMLView

type FieldInputProps

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

type FieldNumberInputOption

type FieldNumberInputOption func(FieldHTMLView) FieldHTMLView

func NumberInput

func NumberInput(inputName string, options ...FieldNumberInputOption) FieldNumberInputOption

func (FieldNumberInputOption) Use

type FieldOption

type FieldOption interface {
	// contains filtered or unexported methods
}

type FieldTextInputOption

type FieldTextInputOption func(FieldHTMLView) FieldHTMLView

func Textbox

func Textbox(inputName string, options ...FieldTextInputOption) FieldTextInputOption

func (FieldTextInputOption) DefaultValue

func (option FieldTextInputOption) DefaultValue(value string) FieldTextInputOption

func (FieldTextInputOption) Rows

func (option FieldTextInputOption) Rows(rows int) FieldTextInputOption

func (FieldTextInputOption) Use

func (option FieldTextInputOption) Use(enhancers ...HTMLEnhancer) FieldTextInputOption

type FormHTMLView

type FormHTMLView struct {
	Method string
	Action string
	// contains filtered or unexported fields
}

FormHTMLView makes <form> with the provided Method and Action <form method="post" action="/pictures" enctype="multipart/form-data" class="mb-4 flex flex-row items-end">

func FormTo

func FormTo(action string, options ...func(form FormHTMLView) FormHTMLView) FormHTMLView

FormTo an action URL

func Multipart

func Multipart(form FormHTMLView) FormHTMLView

func (FormHTMLView) Multipart

func (form FormHTMLView) Multipart() FormHTMLView

Multipart sets the `enctype` attribute to "multipart/form-data"

func (FormHTMLView) With

func (form FormHTMLView) With(view ...HTMLView) FormHTMLView

With adds the provided views as children

type HTMLAttrView

type HTMLAttrView struct {
	Key   string
	Value string
}

HTMLAttrView allows setting HTML attributes

func AriaAttr

func AriaAttr(key string, value string) HTMLAttrView

AriaAttr is for aria attributes such as aria-label or aria-current

func AriaHidden

func AriaHidden() HTMLAttrView

AriaHidden removes the element from the accessibility tree, hiding from screen readers

func AriaLabel

func AriaLabel(value string) HTMLAttrView

AriaLabel sets the aria-label attribute

func CustomAttr

func CustomAttr(key string, value string) HTMLAttrView

CustomAttr is for data attributes such as href or src

func DataAttr

func DataAttr(key string, value string) HTMLAttrView

DataAttr is for data attributes such as data-testid or data-anything

type HTMLClassNameView

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

HTMLClassNameView allows adding to the class attribute

func Class

func Class(classNames ...string) HTMLClassNameView

Class adds a class name

func ClassName

func ClassName(classNames ...string) HTMLClassNameView

ClassName adds a class name

func Tailwind

func Tailwind(additions ...TailwindClassName) HTMLClassNameView

Tailwind adds TailwindCSS class names

func (HTMLClassNameView) Concat

Concat appends the classes from the HTMLClassNameView specified

func (HTMLClassNameView) ConcatClassNames

func (view HTMLClassNameView) ConcatClassNames(additions ClassNames) HTMLClassNameView

ConcatClassNames appends the ClassNames specified

type HTMLElementCore

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

HTMLElementCore is shared by various components to perform much of the work of creating an HTML element node

func (HTMLElementCore) Use

func (core HTMLElementCore) Use(enhancers ...HTMLEnhancer) HTMLElementCore

Use the provided enhancers

type HTMLElementView

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

HTMLElementView can be adapted to many types of HTML elements

func Article

func Article(children ...HTMLView) HTMLElementView

func Aside

func Aside(children ...HTMLView) HTMLElementView

func Button

func Button(children ...HTMLView) HTMLElementView

func Div

func Div(children ...HTMLView) HTMLElementView

func DivWithClasses

func DivWithClasses(classNames ClassNames, children ...HTMLView) HTMLElementView
func Footer(children ...HTMLView) HTMLElementView

func HTMLElementViewOf

func HTMLElementViewOf(tagName string, tagAtom atom.Atom, children []HTMLView) HTMLElementView
func Header(children ...HTMLView) HTMLElementView

func Img

func Img(srcURL string, alt string, enhancers ...HTMLEnhancer) HTMLElementView

func Li

func Li(children ...HTMLView) HTMLElementView
func Link(url string, children ...HTMLView) HTMLElementView

func List

func List(children ...HTMLView) HTMLElementView

func Main

func Main(children ...HTMLView) HTMLElementView
func Nav(children ...HTMLView) HTMLElementView

func Noscript

func Noscript(children ...HTMLView) HTMLElementView

func P

func P(children ...HTMLView) HTMLElementView

func Section

func Section(children ...HTMLView) HTMLElementView

func SubmitButton

func SubmitButton(children ...HTMLView) HTMLElementView

func TextWith

func TextWith(text string, enhancers ...HTMLEnhancer) HTMLElementView

func Ul

func Ul(children ...HTMLView) HTMLElementView

func (HTMLElementView) AddClasses

func (el HTMLElementView) AddClasses(additions ClassNames) HTMLElementView

func (HTMLElementView) ChangeClasses

func (el HTMLElementView) ChangeClasses(changer func(classNames ClassNames) ClassNames) HTMLElementView

func (HTMLElementView) Class

func (el HTMLElementView) Class(classNames ...string) HTMLElementView

func (HTMLElementView) Md

func (basic HTMLElementView) Md(classNames ...TailwindClassName) HTMLElementView

func (HTMLElementView) Tailwind

func (basic HTMLElementView) Tailwind(additions ...TailwindClassName) HTMLElementView

func (HTMLElementView) Use

func (el HTMLElementView) Use(enhancers ...HTMLEnhancer) HTMLElementView

func (HTMLElementView) UseWhen

func (el HTMLElementView) UseWhen(when bool, enhancers ...HTMLEnhancer) HTMLElementView

type HTMLEnhancer

type HTMLEnhancer interface {
	HTMLView
	// contains filtered or unexported methods
}

HTMLEnhancer adds attributes but doesn’t add children

type HTMLText

type HTMLText struct {
	Text string
}

HTMLText represents an HTML text node

func Text

func Text(text string) HTMLText

Text makes a html text node with the given content

type HTMLView

type HTMLView interface {
	// contains filtered or unexported methods
}

HTMLView applies changes to an html.Node, such as making it into an element or text node, or adding attributes

func Combine

func Combine(views ...HTMLView) HTMLView

func H

func H(level int, children ...HTMLView) HTMLView

H can be used to create <h1>, <h2>, etc. The first argument is the number

func When

func When(when bool, child HTMLView) HTMLView

When conditionally renders the first argument when the second argument is true

type Heading

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

Heading lets you render h1, h2, h3, etc

type TailwindClassName

type TailwindClassName string

TailwindClassName is a subset of strings allowed as Tailwind class names

const (
	// MaxWLG max width to lg breakpoint
	MaxWLG TailwindClassName = "max-w-lg"

	// Pt1 padding top of 1
	Pt1 TailwindClassName = "pt-1"
	// Pt2 padding top of 2
	Pt2 TailwindClassName = "pt-2"
	// Pt4 padding top of 4
	Pt4 TailwindClassName = "pt-4"
	// Pt8 padding top of 8
	Pt8 TailwindClassName = "pt-8"

	// Pb1 padding bottom of 1
	Pb1 TailwindClassName = "pb-1"
	// Pb2 padding bottom of 2
	Pb2 TailwindClassName = "pb-2"
	// Pb4 padding bottom of 4
	Pb4 TailwindClassName = "pb-4"
	// Pb8 padding bottom of 8
	Pb8 TailwindClassName = "pb-8"

	// Pl1 padding left of 1
	Pl1 TailwindClassName = "pl-1"
	// Pl2 padding left of 2
	Pl2 TailwindClassName = "pl-2"
	// Pl3 padding left of 3
	Pl3 TailwindClassName = "pl-3"

	// Pr1 padding right of 1
	Pr1 TailwindClassName = "pr-1"
	// Pr2 padding right of 2
	Pr2 TailwindClassName = "pr-2"
	// Pr3 padding right of 3
	Pr3 TailwindClassName = "pr-3"

	// Px3 padding left and right of 3
	Px3 TailwindClassName = "px-3"

	// Py1 padding top and bottom of 1
	Py1 TailwindClassName = "py-1"

	// MxAuto margin left and right of auto
	MxAuto TailwindClassName = "mx-auto"
	// Mb8 margin bottom of 8
	Mb8 TailwindClassName = "mb-8"

	// TextXS text of small size
	TextXS TailwindClassName = "text-xs"
	// TextSM text of small size
	TextSM TailwindClassName = "text-sm"
	// TextBase text of size 1rem
	TextBase TailwindClassName = "text-base"
	// TextXL text of XL size
	TextXL TailwindClassName = "text-xl"
	// Text2XL text of 2XL size
	Text2XL TailwindClassName = "text-2xl"

	// TextBlue300 blue text light 300
	TextBlue300 TailwindClassName = "text-blue-300"

	// BgBlue700 blue background dark 700
	BgBlue700 TailwindClassName = "bg-blue-700"
	// BgBlue800 blue background dark 800
	BgBlue800 TailwindClassName = "bg-blue-800"

	// FontBold bold font weight
	FontBold TailwindClassName = "font-bold"

	// Italic font style
	Italic TailwindClassName = "italic"
	// NotItalic back to roman font style
	NotItalic TailwindClassName = "not-italic"

	// RoundedFull rounded corners in a pill shape
	RoundedFull TailwindClassName = "rounded-full"
)

func Hover

func Hover(baseName TailwindClassName) TailwindClassName

Directories

Path Synopsis
wasm

Jump to

Keyboard shortcuts

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