diff options
author | Markus Wüstenberg | 2020-12-10 13:00:23 +0100 |
---|---|---|
committer | GitHub | 2020-12-10 13:00:23 +0100 |
commit | a76262652b227c95ce140f3698c46f59b79354ac (patch) | |
tree | 15987ad4a4a4f830f0df9fc110faf667fe83514a /components | |
parent | a7e24c6cddaafb98091c3989c9da7779eeba30b5 (diff) | |
download | gomponents-a76262652b227c95ce140f3698c46f59b79354ac.tar.lz gomponents-a76262652b227c95ce140f3698c46f59b79354ac.tar.zst gomponents-a76262652b227c95ce140f3698c46f59b79354ac.zip |
Move elements and attributes into html package (#52)
This makes it easier to use dot-imports. Also updated the readme and examples with new usage, and move the `Classes` helper into the `components` package.
Diffstat (limited to 'components')
-rw-r--r-- | components/attributes.go | 37 | ||||
-rw-r--r-- | components/attributes_test.go | 32 | ||||
-rw-r--r-- | components/documents.go | 29 | ||||
-rw-r--r-- | components/documents_test.go | 13 |
4 files changed, 89 insertions, 22 deletions
diff --git a/components/attributes.go b/components/attributes.go new file mode 100644 index 0000000..dc7ef9b --- /dev/null +++ b/components/attributes.go @@ -0,0 +1,37 @@ +package components + +import ( + "io" + "sort" + "strings" + + g "github.com/maragudk/gomponents" + "github.com/maragudk/gomponents/html" +) + +// Classes is a map of strings to booleans, which Renders to an attribute with name "class". +// The attribute value is a sorted, space-separated string of all the map keys, +// for which the corresponding map value is true. +type Classes map[string]bool + +func (c Classes) Render(w io.Writer) error { + var included []string + for c, include := range c { + if include { + included = append(included, c) + } + } + sort.Strings(included) + return html.Class(strings.Join(included, " ")).Render(w) +} + +func (c Classes) Type() g.NodeType { + return g.AttributeType +} + +// String satisfies fmt.Stringer. +func (c Classes) String() string { + var b strings.Builder + _ = c.Render(&b) + return b.String() +} diff --git a/components/attributes_test.go b/components/attributes_test.go new file mode 100644 index 0000000..bf3e93b --- /dev/null +++ b/components/attributes_test.go @@ -0,0 +1,32 @@ +package components_test + +import ( + "testing" + + g "github.com/maragudk/gomponents" + "github.com/maragudk/gomponents/assert" + c "github.com/maragudk/gomponents/components" +) + +func TestClasses(t *testing.T) { + t.Run("given a map, returns sorted keys from the map with value true", func(t *testing.T) { + assert.Equal(t, ` class="boheme-hat hat partyhat"`, c.Classes{ + "boheme-hat": true, + "hat": true, + "partyhat": true, + "turtlehat": false, + }) + }) + + t.Run("renders as attribute in an element", func(t *testing.T) { + e := g.El("div", c.Classes{"hat": true}) + assert.Equal(t, `<div class="hat"></div>`, e) + }) + + t.Run("also works with fmt", func(t *testing.T) { + a := c.Classes{"hat": true} + if a.String() != ` class="hat"` { + t.FailNow() + } + }) +} diff --git a/components/documents.go b/components/documents.go index 5e96466..e2d3a22 100644 --- a/components/documents.go +++ b/components/documents.go @@ -1,15 +1,14 @@ -// Package components provides high-level components that are composed of low-level elements and attributes. +// Package components provides high-level components and helpers that are composed of low-level elements and attributes. package components import ( g "github.com/maragudk/gomponents" - "github.com/maragudk/gomponents/attr" - "github.com/maragudk/gomponents/el" + . "github.com/maragudk/gomponents/html" ) -// DocumentProps for HTML5. +// HTML5Props for HTML5. // Title is set no matter what, Description and Language elements only if the strings are non-empty. -type DocumentProps struct { +type HTML5Props struct { Title string Description string Language string @@ -18,24 +17,24 @@ type DocumentProps struct { } // HTML5 document template. -func HTML5(p DocumentProps) g.NodeFunc { +func HTML5(p HTML5Props) g.NodeFunc { var lang, description g.Node if p.Language != "" { - lang = attr.Lang(p.Language) + lang = Lang(p.Language) } if p.Description != "" { - description = el.Meta(attr.Name("description"), attr.Content(p.Description)) + description = Meta(Name("description"), Content(p.Description)) } - return el.Document( - el.HTML(lang, - el.Head( - el.Meta(attr.Charset("utf-8")), - el.Meta(attr.Name("viewport"), attr.Content("width=device-width, initial-scale=1")), - el.Title(p.Title), + return Document( + HTML(lang, + Head( + Meta(Charset("utf-8")), + Meta(Name("viewport"), Content("width=device-width, initial-scale=1")), + TitleEl(p.Title), description, g.Group(p.Head), ), - el.Body(g.Group(p.Body)), + Body(g.Group(p.Body)), ), ) } diff --git a/components/documents_test.go b/components/documents_test.go index 863ac96..07f8697 100644 --- a/components/documents_test.go +++ b/components/documents_test.go @@ -5,26 +5,25 @@ import ( g "github.com/maragudk/gomponents" "github.com/maragudk/gomponents/assert" - "github.com/maragudk/gomponents/attr" - c "github.com/maragudk/gomponents/components" - "github.com/maragudk/gomponents/el" + . "github.com/maragudk/gomponents/components" + . "github.com/maragudk/gomponents/html" ) func TestHTML5(t *testing.T) { t.Run("returns an html5 document template", func(t *testing.T) { - e := c.HTML5(c.DocumentProps{ + e := HTML5(HTML5Props{ Title: "Hat", Description: "Love hats.", Language: "en", - Head: []g.Node{el.Link(attr.Rel("stylesheet"), attr.Href("/hat.css"))}, - Body: []g.Node{el.Div()}, + Head: []g.Node{Link(Rel("stylesheet"), Href("/hat.css"))}, + Body: []g.Node{Div()}, }) assert.Equal(t, `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Hat</title><meta name="description" content="Love hats."><link rel="stylesheet" href="/hat.css"></head><body><div></div></body></html>`, e) }) t.Run("returns no language, description, and extra head/body elements if empty", func(t *testing.T) { - e := c.HTML5(c.DocumentProps{ + e := HTML5(HTML5Props{ Title: "Hat", }) |