├── .github └── workflows │ └── go.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── attrs ├── README.md ├── attrs.go ├── utils.go └── utils_test.go ├── elem.go ├── elem_test.go ├── elements.go ├── elements_test.go ├── examples ├── htmx-counter │ ├── README.md │ ├── go.mod │ └── main.go ├── htmx-fiber-counter │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go ├── htmx-fiber-form │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go ├── htmx-fiber-todo │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go └── stylemanager-demo │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go ├── go.mod ├── go.sum ├── htmx ├── README.md └── htmx.go ├── logo.png ├── styles ├── README.md ├── STYLEMANAGER.md ├── constants.go ├── stylemanager.go ├── stylemanager_test.go ├── styles.go ├── styles_test.go ├── utils.go └── utils_test.go ├── utils.go └── utils_test.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v4 21 | with: 22 | go-version: '1.21.x' 23 | 24 | - name: Build 25 | run: go build -v ./... 26 | 27 | - name: Test 28 | run: go test -v ./... 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Chase Fleming 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test tidy 2 | 3 | tidy: 4 | @echo "Tidying up module..." 5 | go mod tidy 6 | 7 | test: 8 | @echo "Running tests..." 9 | go test ./... -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | `elem` is a lightweight Go library for creating HTML elements programmatically. Utilizing the strong typing features of Go, `elem` ensures type safety in defining and manipulating HTML elements, minimizing potential runtime errors. It simplifies the generation of HTML views by providing a simple and intuitive way to create elements and set their attributes, properties, and content. 4 | 5 | ## Features 6 | 7 | - Easily create HTML elements with Go code. 8 | - Type-safe definition and manipulation of elements, attributes, and properties. 9 | - Supports common HTML elements and attributes. 10 | - Utilities for simplified element generation and manipulation. 11 | - Advanced CSS styling capabilities with the [styles](styles/README.md) subpackage. 12 | - Use the [`StyleManager`](styles/STYLEMANAGER.md) for advanced CSS features like pseudo-classes, animations, and media queries. 13 | 14 | ## Installation 15 | 16 | To install `elem`, use `go get`: 17 | 18 | ```bash 19 | go get github.com/chasefleming/elem-go 20 | ``` 21 | 22 | ## Usage 23 | 24 | Import the `elem` package in your Go code: 25 | 26 | ```go 27 | import ( 28 | "github.com/chasefleming/elem-go" 29 | "github.com/chasefleming/elem-go/attrs" 30 | "github.com/chasefleming/elem-go/styles" 31 | ) 32 | ``` 33 | 34 | ### Creating Elements 35 | 36 | Here's an example of creating a `
` elements using elem: 37 | 38 | ```go 39 | content := elem.Div(attrs.Props{ 40 | attrs.ID: "container", 41 | attrs.Class: "my-class", 42 | }, 43 | elem.H1(nil, elem.Text("Hello, Elem!")), 44 | elem.H2(nil, elem.Text("Subheading")), 45 | elem.P(nil, elem.Text("This is a paragraph.")), 46 | ) 47 | ``` 48 | 49 | When the above Go code is executed and the `.Render()` method is called, it produces the following HTML: 50 | 51 | ```html 52 |
This is a paragraph.
56 |Custom HTML content
Custom HTML content
More content here...
element.
42 | func Blockquote(attrs attrs.Props, children ...Node) *Element {
43 | return newElement("blockquote", attrs, children...)
44 | }
45 |
46 | // Code creates a element.
47 | func Code(attrs attrs.Props, children ...Node) *Element {
48 | return newElement("code", attrs, children...)
49 | }
50 |
51 | // Div creates a element.
52 | func Div(attrs attrs.Props, children ...Node) *Element {
53 | return newElement("div", attrs, children...)
54 | }
55 |
56 | // Em creates an element.
57 | func Em(attrs attrs.Props, children ...Node) *Element {
58 | return newElement("em", attrs, children...)
59 | }
60 |
61 | // H1 creates an element.
62 | func H1(attrs attrs.Props, children ...Node) *Element {
63 | return newElement("h1", attrs, children...)
64 | }
65 |
66 | // H2 creates an element.
67 | func H2(attrs attrs.Props, children ...Node) *Element {
68 | return newElement("h2", attrs, children...)
69 | }
70 |
71 | // H3 creates an element.
72 | func H3(attrs attrs.Props, children ...Node) *Element {
73 | return newElement("h3", attrs, children...)
74 | }
75 |
76 | // H4 creates an element.
77 | func H4(attrs attrs.Props, children ...Node) *Element {
78 | return newElement("h4", attrs, children...)
79 | }
80 |
81 | // H5 creates an element.
82 | func H5(attrs attrs.Props, children ...Node) *Element {
83 | return newElement("h5", attrs, children...)
84 | }
85 |
86 | // H6 creates an element.
87 | func H6(attrs attrs.Props, children ...Node) *Element {
88 | return newElement("h6", attrs, children...)
89 | }
90 |
91 | // Hgroup creates an element.
92 | func Hgroup(attrs attrs.Props, children ...Node) *Element {
93 | return newElement("hgroup", attrs, children...)
94 | }
95 |
96 | // Hr creates an
element.
97 | func Hr(attrs attrs.Props) *Element {
98 | return newElement("hr", attrs)
99 | }
100 |
101 | // I creates an element.
102 | func I(attrs attrs.Props, children ...Node) *Element {
103 | return newElement("i", attrs, children...)
104 | }
105 |
106 | // P creates a element.
107 | func P(attrs attrs.Props, children ...Node) *Element {
108 | return newElement("p", attrs, children...)
109 | }
110 |
111 | // Pre creates a
element.
112 | func Pre(attrs attrs.Props, children ...Node) *Element {
113 | return newElement("pre", attrs, children...)
114 | }
115 |
116 | // Span creates a element.
117 | func Span(attrs attrs.Props, children ...Node) *Element {
118 | return newElement("span", attrs, children...)
119 | }
120 |
121 | // Strong creates a element.
122 | func Strong(attrs attrs.Props, children ...Node) *Element {
123 | return newElement("strong", attrs, children...)
124 | }
125 |
126 | // Sub creates a element.
127 | func Sub(attrs attrs.Props, children ...Node) *Element {
128 | return newElement("sub", attrs, children...)
129 | }
130 |
131 | // Sup creates a element.
132 | func Sup(attrs attrs.Props, children ...Node) *Element {
133 | return newElement("sup", attrs, children...)
134 | }
135 |
136 | // B creates a element.
137 | func B(attrs attrs.Props, children ...Node) *Element {
138 | return newElement("b", attrs, children...)
139 | }
140 |
141 | // U creates a element.
142 | func U(attrs attrs.Props, children ...Node) *Element {
143 | return newElement("u", attrs, children...)
144 | }
145 |
146 | // Text creates a TextNode.
147 | func Text(content string) TextNode {
148 | return TextNode(content)
149 | }
150 |
151 | // Comment creates a CommentNode.
152 | func Comment(comment string) CommentNode {
153 | return CommentNode(comment)
154 | }
155 |
156 | // ========== Lists ==========
157 |
158 | // Li creates an element.
159 | func Li(attrs attrs.Props, children ...Node) *Element {
160 | return newElement("li", attrs, children...)
161 | }
162 |
163 | // Ul creates a element.
164 | func Ul(attrs attrs.Props, children ...Node) *Element {
165 | return newElement("ul", attrs, children...)
166 | }
167 |
168 | // Ol creates an element.
169 | func Ol(attrs attrs.Props, children ...Node) *Element {
170 | return newElement("ol", attrs, children...)
171 | }
172 |
173 | // Dl creates a element.
174 | func Dl(attrs attrs.Props, children ...Node) *Element {
175 | return newElement("dl", attrs, children...)
176 | }
177 |
178 | // Dt creates a - element.
179 | func Dt(attrs attrs.Props, children ...Node) *Element {
180 | return newElement("dt", attrs, children...)
181 | }
182 |
183 | // Dd creates a
- element.
184 | func Dd(attrs attrs.Props, children ...Node) *Element {
185 | return newElement("dd", attrs, children...)
186 | }
187 |
188 | // ========== Forms ==========
189 |
190 | // Button creates a