1
0

Simplify available elements (#55)

`a`, `form`, `img`, `input`, `label`, `option`, `progress`, `select`, and `textarea` are now just regular elements (without helper parameters), because:
- Sometimes the use case doesn't fit (`a` as anchor without href, for example)
- There's no reason these are special among the others, so streamlining them makes sense

Also added new attributes `action`, `alt`, `for`, `method` that I had somehow missed.
This commit is contained in:
Markus Wüstenberg 2020-12-10 14:20:33 +01:00 committed by GitHub
parent 100ae9e830
commit febffb600d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 67 additions and 112 deletions

View File

@ -78,7 +78,7 @@ func Navbar(currentPath string) g.Node {
}
func NavbarLink(href, name, currentPath string) g.Node {
return A(href, c.Classes{"is-active": currentPath == href}, g.Text(name))
return A(Href(href), c.Classes{"is-active": currentPath == href}, g.Text(name))
}
```
@ -129,7 +129,7 @@ func Navbar(currentPath string) g.Node {
}
func NavbarLink(href, name, currentPath string) g.Node {
return A(href, c.Classes{"is-active": currentPath == href}, g.Text(name))
return A(Href(href), c.Classes{"is-active": currentPath == href}, g.Text(name))
}
```

View File

@ -40,5 +40,5 @@ func Navbar(currentPath string) g.Node {
}
func NavbarLink(href, name, currentPath string) g.Node {
return A(href, Classes{"is-active": currentPath == href}, g.Text(name))
return A(Href(href), Classes{"is-active": currentPath == href}, g.Text(name))
}

View File

@ -64,7 +64,7 @@ func navbar(props navbarProps) g.Node {
lis := g.Map(len(items), func(i int) g.Node {
item := items[i]
return h.Li(
h.A(item.path, c.Classes(map[string]bool{"is-active": props.path == item.path}), g.Text(item.text)),
h.A(h.Href(item.path), c.Classes(map[string]bool{"is-active": props.path == item.path}), g.Text(item.text)),
)
})
return h.Ul(h.Class("nav"), g.Group(lis))

View File

@ -48,6 +48,14 @@ func Accept(v string) g.Node {
return g.Attr("accept", v)
}
func Action(v string) g.Node {
return g.Attr("action", v)
}
func Alt(v string) g.Node {
return g.Attr("alt", v)
}
func AutoComplete(v string) g.Node {
return g.Attr("autocomplete", v)
}
@ -68,6 +76,10 @@ func Content(v string) g.Node {
return g.Attr("content", v)
}
func For(v string) g.Node {
return g.Attr("for", v)
}
func FormAttr(v string) g.Node {
return g.Attr("form", v)
}
@ -96,6 +108,10 @@ func MaxLength(v string) g.Node {
return g.Attr("maxlength", v)
}
func Method(v string) g.Node {
return g.Attr("method", v)
}
func Min(v string) g.Node {
return g.Attr("min", v)
}

View File

@ -34,11 +34,14 @@ func TestBooleanAttributes(t *testing.T) {
func TestSimpleAttributes(t *testing.T) {
cases := map[string]func(string) g.Node{
"accept": Accept,
"action": Action,
"alt": Alt,
"autocomplete": AutoComplete,
"charset": Charset,
"class": Class,
"cols": Cols,
"content": Content,
"for": For,
"form": FormAttr,
"height": Height,
"href": Href,
@ -46,6 +49,7 @@ func TestSimpleAttributes(t *testing.T) {
"lang": Lang,
"max": Max,
"maxlength": MaxLength,
"method": Method,
"min": Min,
"minlength": MinLength,
"name": Name,

View File

@ -4,16 +4,11 @@
package html
import (
"fmt"
"io"
g "github.com/maragudk/gomponents"
)
func A(href string, children ...g.Node) g.NodeFunc {
return g.El("a", g.Attr("href", href), g.Group(children))
}
// Doctype returns a special kind of Node that prefixes its sibling with the string "<!doctype html>".
func Doctype(sibling g.Node) g.NodeFunc {
return func(w io.Writer) error {
@ -24,48 +19,8 @@ func Doctype(sibling g.Node) g.NodeFunc {
}
}
// FormEl returns an element with name "form", the given action and method attributes, and the given children.
func FormEl(action, method string, children ...g.Node) g.NodeFunc {
return g.El("form", g.Attr("action", action), g.Attr("method", method), g.Group(children))
}
func Img(src, alt string, children ...g.Node) g.NodeFunc {
return g.El("img", g.Attr("src", src), g.Attr("alt", alt), g.Group(children))
}
// Input returns an element with name "input", the given type and name attributes, and the given children.
// Note that "type" is a keyword in Go, so the parameter is called typ.
func Input(typ, name string, children ...g.Node) g.NodeFunc {
return g.El("input", g.Attr("type", typ), g.Attr("name", name), g.Group(children))
}
// Label returns an element with name "label", the given for attribute, and the given children.
// Note that "for" is a keyword in Go, so the parameter is called forr.
func Label(forr string, children ...g.Node) g.NodeFunc {
return g.El("label", g.Attr("for", forr), g.Group(children))
}
// Option returns an element with name "option", the given text content and value attribute, and the given children.
func Option(text, value string, children ...g.Node) g.NodeFunc {
return g.El("option", g.Attr("value", value), g.Text(text), g.Group(children))
}
// Progress returns an element with name "progress", the given value and max attributes, and the given children.
func Progress(value, max float64, children ...g.Node) g.NodeFunc {
return g.El("progress",
g.Attr("value", fmt.Sprintf("%v", value)),
g.Attr("max", fmt.Sprintf("%v", max)),
g.Group(children))
}
// Select returns an element with name "select", the given name attribute, and the given children.
func Select(name string, children ...g.Node) g.NodeFunc {
return g.El("select", g.Attr("name", name), g.Group(children))
}
// Textarea returns an element with name "textarea", the given name attribute, and the given children.
func Textarea(name string, children ...g.Node) g.NodeFunc {
return g.El("textarea", g.Attr("name", name), g.Group(children))
func A(children ...g.Node) g.NodeFunc {
return g.El("a", children...)
}
func Address(children ...g.Node) g.NodeFunc {
@ -156,6 +111,10 @@ func Embed(children ...g.Node) g.NodeFunc {
return g.El("embed", children...)
}
func FormEl(children ...g.Node) g.NodeFunc {
return g.El("form", children...)
}
func FieldSet(children ...g.Node) g.NodeFunc {
return g.El("fieldset", children...)
}
@ -192,6 +151,18 @@ func IFrame(children ...g.Node) g.NodeFunc {
return g.El("iframe", children...)
}
func Img(children ...g.Node) g.NodeFunc {
return g.El("img", children...)
}
func Input(children ...g.Node) g.NodeFunc {
return g.El("input", children...)
}
func Label(children ...g.Node) g.NodeFunc {
return g.El("label", children...)
}
func Legend(children ...g.Node) g.NodeFunc {
return g.El("legend", children...)
}
@ -240,6 +211,10 @@ func OptGroup(children ...g.Node) g.NodeFunc {
return g.El("optgroup", children...)
}
func Option(children ...g.Node) g.NodeFunc {
return g.El("option", children...)
}
func P(children ...g.Node) g.NodeFunc {
return g.El("p", children...)
}
@ -256,6 +231,10 @@ func Pre(children ...g.Node) g.NodeFunc {
return g.El("pre", children...)
}
func Progress(children ...g.Node) g.NodeFunc {
return g.El("progress", children...)
}
func Script(children ...g.Node) g.NodeFunc {
return g.El("script", children...)
}
@ -264,6 +243,10 @@ func Section(children ...g.Node) g.NodeFunc {
return g.El("section", children...)
}
func Select(children ...g.Node) g.NodeFunc {
return g.El("select", children...)
}
func Source(children ...g.Node) g.NodeFunc {
return g.El("source", children...)
}
@ -296,6 +279,10 @@ func Td(children ...g.Node) g.NodeFunc {
return g.El("td", children...)
}
func Textarea(children ...g.Node) g.NodeFunc {
return g.El("textarea", children...)
}
func TFoot(children ...g.Node) g.NodeFunc {
return g.El("tfoot", children...)
}
@ -356,32 +343,26 @@ func FigCaption(text string, children ...g.Node) g.NodeFunc {
return g.El("figcaption", g.Text(text), g.Group(children))
}
// H1 returns an element with name "h1", the given text content, and the given children.
func H1(text string, children ...g.Node) g.NodeFunc {
return g.El("h1", g.Text(text), g.Group(children))
}
// H2 returns an element with name "h2", the given text content, and the given children.
func H2(text string, children ...g.Node) g.NodeFunc {
return g.El("h2", g.Text(text), g.Group(children))
}
// H3 returns an element with name "h3", the given text content, and the given children.
func H3(text string, children ...g.Node) g.NodeFunc {
return g.El("h3", g.Text(text), g.Group(children))
}
// H4 returns an element with name "h4", the given text content, and the given children.
func H4(text string, children ...g.Node) g.NodeFunc {
return g.El("h4", g.Text(text), g.Group(children))
}
// H5 returns an element with name "h5", the given text content, and the given children.
func H5(text string, children ...g.Node) g.NodeFunc {
return g.El("h5", g.Text(text), g.Group(children))
}
// H6 returns an element with name "h6", the given text content, and the given children.
func H6(text string, children ...g.Node) g.NodeFunc {
return g.El("h6", g.Text(text), g.Group(children))
}

View File

@ -27,63 +27,9 @@ func TestDoctype(t *testing.T) {
})
}
func TestFormEl(t *testing.T) {
t.Run("returns a form element with action and method attributes", func(t *testing.T) {
assert.Equal(t, `<form action="/" method="post"></form>`, FormEl("/", "post"))
})
}
func TestInput(t *testing.T) {
t.Run("returns an input element with attributes type and name", func(t *testing.T) {
assert.Equal(t, `<input type="text" name="hat">`, Input("text", "hat"))
})
}
func TestLabel(t *testing.T) {
t.Run("returns a label element with attribute for", func(t *testing.T) {
assert.Equal(t, `<label for="hat">Hat</label>`, Label("hat", g.Text("Hat")))
})
}
func TestOption(t *testing.T) {
t.Run("returns an option element with attribute label and content", func(t *testing.T) {
assert.Equal(t, `<option value="hat">Hat</option>`, Option("Hat", "hat"))
})
}
func TestProgress(t *testing.T) {
t.Run("returns a progress element with attributes value and max", func(t *testing.T) {
assert.Equal(t, `<progress value="5.5" max="10"></progress>`, Progress(5.5, 10))
})
}
func TestSelect(t *testing.T) {
t.Run("returns a select element with attribute name", func(t *testing.T) {
assert.Equal(t, `<select name="hat"><option value="partyhat">Partyhat</option></select>`,
Select("hat", Option("Partyhat", "partyhat")))
})
}
func TestTextarea(t *testing.T) {
t.Run("returns a textarea element with attribute name", func(t *testing.T) {
assert.Equal(t, `<textarea name="hat"></textarea>`, Textarea("hat"))
})
}
func TestA(t *testing.T) {
t.Run("returns an a element with a href attribute", func(t *testing.T) {
assert.Equal(t, `<a href="#">hat</a>`, A("#", g.Text("hat")))
})
}
func TestImg(t *testing.T) {
t.Run("returns an img element with href and alt attributes", func(t *testing.T) {
assert.Equal(t, `<img src="hat.png" alt="hat" id="image">`, Img("hat.png", "hat", g.Attr("id", "image")))
})
}
func TestSimpleElements(t *testing.T) {
cases := map[string]func(...g.Node) g.NodeFunc{
"a": A,
"address": Address,
"article": Article,
"aside": Aside,
@ -104,11 +50,13 @@ func TestSimpleElements(t *testing.T) {
"fieldset": FieldSet,
"figure": Figure,
"footer": Footer,
"form": FormEl,
"head": Head,
"header": Header,
"hgroup": HGroup,
"html": HTML,
"iframe": IFrame,
"label": Label,
"legend": Legend,
"li": Li,
"main": Main,
@ -119,11 +67,14 @@ func TestSimpleElements(t *testing.T) {
"object": Object,
"ol": Ol,
"optgroup": OptGroup,
"option": Option,
"p": P,
"picture": Picture,
"pre": Pre,
"progress": Progress,
"script": Script,
"section": Section,
"select": Select,
"span": Span,
"style": StyleEl,
"summary": Summary,
@ -131,6 +82,7 @@ func TestSimpleElements(t *testing.T) {
"table": Table,
"tbody": TBody,
"td": Td,
"textarea": Textarea,
"tfoot": TFoot,
"th": Th,
"thead": THead,
@ -154,6 +106,8 @@ func TestSimpleVoidKindElements(t *testing.T) {
"col": Col,
"embed": Embed,
"hr": Hr,
"img": Img,
"input": Input,
"link": Link,
"meta": Meta,
"param": Param,