Releases: chasefleming/elem-go
Version 0.20.0
✨ Enhancements
-
New htmx constants: Added extensive support for htmx attributes and
hx-on::event
attributes using a--
syntax for universal compatibility. This update more closely alignselem-go
with htmx version 1.9.10, enabling developers to implement dynamic web functionalities with improved ease and safety. -
New Attribute Constants: Introduced new attribute constants for
integrity
andcrossorigin
for script elements, enhancing security and resource sharing capabilities in web applications. -
Style Constant for Object Fit: Added a style constant for
object-fit
property, allowing for more control over the visual rendering of images and videos, ensuring they fit their containers in a visually appealing manner.
🙏 Thanks to Contributors
Version 0.19.0
🚀 New Features
Added Support for <h4>
, <h5>
, <h6>
, and <hgroup>
Elements
Support for the <h4>
, <h5>
, <h6>
, and <hgroup>
HTML elements has been added, broadening the scope for semantic text structuring and document outline organization.
Usage Examples
Create a section with nested headings using elem.H4()
, elem.H5()
, and elem.H6()
:
sectionContent := elem.Div(nil,
elem.H4(nil, elem.Text("Section Heading Level 4")),
elem.H5(nil, elem.Text("Subsection Heading Level 5")),
elem.H6(nil, elem.Text("Subsubsection Heading Level 6")),
)
This will output:
<div>
<h4>Section Heading Level 4</h4>
<h5>Subsection Heading Level 5</h5>
<h6>Subsubsection Heading Level 6</h6>
</div>
Group headings together semantically using elem.Hgroup()
:
headingGroup := elem.Hgroup(nil,
elem.H1(nil, elem.Text("Main Title")),
elem.H2(nil, elem.Text("Subtitle")),
)
This will output:
<hgroup>
<h1>Main Title</h1>
<h2>Subtitle</h2>
</hgroup>
🙏 Thanks to Contributors
Version 0.18.0
🚀 New Features
Added <map>
and <area>
Element Support
Support for the <map>
and <area>
HTML elements has been added, enhancing the capability of creating interactive image maps.
Usage Examples
Create a <map>
element with elem.Map()
and define clickable areas using elem.Area()
:
imageMap := elem.Map(attrs.Props{attrs.Name: "map1"},
elem.Area(attrs.Props{
attrs.Alt: "Area 1",
attrs.Coords: "34,44,270,350",
attrs.Href: "#area1",
attrs.Shape: "rect",
}),
)
This will output:
<map name="map1">
<area alt="Area 1" coords="34,44,270,350" href="#area1" shape="rect">
</map>
Other Changes
- Attributes for
"shape"
,"coords"
, and"usemap"
have been added to the attributes subpackage. - A new constant for "
backdrop-filter"
is now available in the styles package. - Updated the todo example to use
utils.CopyString
for optimized memory management in line with Fiber's performance strategy.
🙏 Thanks to Contributors
Version 0.17.0
🚀 New Features and Enhancements
Support for <optgroup>
Element
The Optgroup
function for creating <optgroup>
elements has been added. This update allows for better organization in forms with numerous options by grouping <option>
elements within <select>
dropdowns.
Example Usage
el := Select(attrs.Props{attrs.Name: "cars"},
Optgroup(attrs.Props{attrs.Label: "Swedish Cars"},
Option(attrs.Props{attrs.Value: "volvo"}, Text("Volvo")),
Option(attrs.Props{attrs.Value: "saab"}, Text("Saab"))),
Optgroup(attrs.Props{attrs.Label: "German Cars"},
Option(attrs.Props{attrs.Value: "mercedes"}, Text("Mercedes")),
Option(attrs.Props{attrs.Value: "audi"}, Text("Audi")))
)
This will render the following HTML:
<select name="cars">
<optgroup label="Swedish Cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>
Doctype Preamble Now Added With elem.Html
elem.Html
now automatically includes the <!DOCTYPE html>
preamble at the beginning of the HTML document to ensure compliance with modern web standards and prevent rendering in legacy/quirks mode.
New RenderWithOptions
Method for Custom Render Options
The new RenderWithOptions
method has been introduced to provide more flexibility in rendering. For instance, if you need to disable the automatic HTML preamble (now included by default in elem.Html
), you can do so using this method. This method takes a RenderOptions
struct with a boolean option for DisableHtmlPreamble
.
Example Usage
options := RenderOptions{DisableHtmlPreamble: true}
htmlString := myHtmlElement.RenderWithOptions(options)
⚠️ Breaking Changes
The public NewElement
function has been made private and renamed to newElement
. Users relying on this function directly in their code will need to update their usage accordingly. If you require additional elements not currently available in the repository, please create an issue to request them.
🙏 Thanks to Contributors
Version 0.16.0
🚀 New Features
elem.None
for Conditional Rendering and Empty Elements
None
now simplifies cases where conditional rendering requires either an element or no output at all. The function provides a straightforward way to express the absence of an element without compromising the readability or structure of your code.
In conditional rendering, None
serves as an ideal placeholder for cases where no output is required. For example, when using None
in conjunction with the If
function, it allows for cleaner and more expressive code. Consider a scenario where you need to render a welcome message conditionally:
showWelcomeMessage := false
welcomeMessage := elem.Div(nil, elem.Text("Welcome to our website!"))
content := elem.Div(nil,
elem.If[elem.Node](showWelcomeMessage, welcomeMessage, elem.None())
)
Here, welcomeMessage
is only rendered if showWelcomeMessage
is true
. Otherwise, None
ensures that there is no output.
None
also makes it straightforward to create explicitly empty elements like <div></div>
, useful in various layout and design contexts:
emptyDiv := elem.Div(nil, elem.None())
// Outputs: <div></div>
Version 0.15.0
🚀 New Features
Raw
HTML Insertion
The Raw
function has been added to allow direct insertion of raw HTML content into the document structure. This function is particularly useful for rendering HTML strings as part of the final output, without any modification or parsing. It offers a convenient way to integrate HTML content generated outside the elem-go
environment.
Example Usage
rawHTML := `<div class="custom-html"><p>Custom HTML content</p></div>`
content := elem.Div(nil,
elem.H1(nil, elem.Text("Hello, World!")),
elem.Raw(rawHTML), // Inserting the raw HTML
elem.P(nil, elem.Text("More content here...")),
)
htmlOutput := content.Render()
NOTE: Users should ensure to sanitize any HTML content from untrusted sources before using the
Raw
function to prevent security risks like XSS (Cross-Site Scripting) attacks.
Version 0.14.0
🚀 New Features
Introduction of DataAttr
for Custom Data Attributes
This new function enables the addition of custom data attributes to HTML elements.
Example Usage
Div(attrs.Props{attrs.DataAttr("theme"): "cupcake"}, Text("foobar"))
// <div data-theme="cupcake">foobar</div>
Expanded ARIA Attributes for Accessibility
A comprehensive set of ARIA (Accessible Rich Internet Applications) attributes has been added to the attrs subpackage. For a full list of the new ARIA attributes, see the constants in the attrs subpackage.
Added Various Attributes
Support for step
and minlength
has been added to our attributes constants.You can access these from the attrs
subpackage as attrs.Step
and attrs.Minlength
.
⚠️ Deprecations
Standardization of Constants in the attrs
Package
Several constants have been renamed to adhere to Go's naming conventions.
AllowFullScreen
→AllowFullscreen
ReferrerPolicy
→Referrerpolicy
NoValidate
→Novalidate
MaxLength
→Maxlength
DateTime
→Datetime
CrossOrigin
→Crossorigin
SrcDoc
→Srcdoc
IsMap
→Ismap
Users are advised to update their code to the new standards. The deprecated constants will remain available for a transition period, but will be removed in future releases.
🙏 Thanks to Contributors
Version 0.13.0
🚀 New Features
HTML Comments
This new utility allows you to easily add HTML comments into your generated HTML.
comment := elem.Comment("Section: Main Content Start")
// Generates: <!-- Section: Main Content Start -->
<iframe>
Support
You can now integrate <iframe>
into your HTML with the new IFrame
function.
iframe := elem.IFrame(attrs.Props{
attrs.Src: "https://www.youtube.com/embed/446E-r0rXHI",
attrs.AllowFullScreen: "true",
})
// Generates <iframe allowfullscreen src="https://www.youtube.com/embed/446E-r0rXHI"></iframe>
<audio>
and <video>
Elements
Enhance your HTML with multimedia content using our new Audio
and Video
functions.
Audio Example
audio := elem.Audio(attrs.Props{attrs.Controls: "true"},
elem.Source(attrs.Props{attrs.Src: "audio.mp3", attrs.Type: "audio/mpeg"}),
elem.Source(attrs.Props{attrs.Src: "audio.ogg", attrs.Type: "audio/ogg"}),
elem.Text("Your browser does not support the audio tag."),
)
// Generates <audio controls><source src="audio.mp3" type="audio/mpeg"><source src="audio.ogg" type="audio/ogg">Your browser does not support the audio tag.</audio>
Video Example
video := elem.Video(attrs.Props{attrs.Width: "320", attrs.Height: "240", attrs.Controls: "true"},
elem.Source(attrs.Props{attrs.Src: "movie.mp4", attrs.Type: "video/mp4"}),
elem.Source(attrs.Props{attrs.Src: "movie.ogg", attrs.Type: "video/ogg"}),
elem.Text("Your browser does not support the video tag."),
)
// Generates <video controls height="240" width="320"><source src="movie.mp4" type="video/mp4"><source src="movie.ogg" type="video/ogg">Your browser does not support the video tag.</video>
🙏 Thanks to Contributors
Version 0.12.0
🚀 New Features
Merge
Function for styles.Props
Developers can now combine multiple style props objects into one with the new Merge
method. This feature is particularly useful for applying conditional styles on top of base styles, depending on state or other factors.
Example Usage
// Example style definitions
baseButtonStyle := styles.Props{
Padding: "10px 15px",
Border: "none",
FontWeight: "bold",
}
primaryStyles := styles.Props{
BackgroundColor: "blue",
Color: "white",
}
secondaryStyles := styles.Props{
BackgroundColor: "red",
Color: "white",
}
// Merging styles with the new Merge function
primaryButtonStyles := styles.Merge(baseButtonStyle, primaryStyles)
secondaryButtonStyles := styles.Merge(baseButtonStyle, secondaryStyles)
In the Merge
function, later style objects take precedence over earlier ones for properties defined in multiple style objects. This allows for fine-grained control over the styling precedence.
Style
and CSS
Functions for Embedding CSS
Two new functions, Style
and CSS
, have been introduced to streamline the creation of <style>
tags for embedding raw CSS into HTML documents.
Style
Function
The Style
function creates an *Element
struct representing a <style>
tag.
Example Usage
// Defining raw CSS content
cssContent := `
body { background-color: #f0f0f0; }
h1 { color: #333; }
`
// Creating a <style> tag with the CSS content
styleTag := elem.Style(nil, styles.CSS(cssContent))
// Creating an HTML document with the <style> tag included in the <head>
document := elem.Html(nil,
elem.Head(nil,
styleTag,
),
// ... other body elements
)
The CSS
function within the Style
tag helper ensures that CSS is correctly embedded and applied within the HTML document.
Version 0.11.0
This update introduces refactoring to the handling of attributes and styles within the elem-go
library to resolve naming conflicts and improve the overall structure.
⚠️ Breaking Changes
Below are the breaking changes and examples of how to update your code accordingly:
1. Refactoring elem.Attrs
to attrs.Props
To avoid naming conflicts with the HTML attribute names and provide a clearer distinction, elem.Attrs
has been renamed to attrs.Props
. This change emphasizes that these are properties for elements rather than direct attributes.
Old Usage:
div := elem.Div(elem.Attrs{
attrs.ID: "content",
attrs.Class: "main-content",
})
New Usage:
div := elem.Div(attrs.Props{
attrs.ID: "content",
attrs.Class: "main-content",
})
Action Required: Replace all instances of elem.Attrs
with attrs.Props
.
2. Refactoring elem.Style
to styles.Props
To differentiate style properties from other attributes and ensure they are treated distinctly within the library, elem.Style
has been refactored to styles.Props
. This allows for a more modular approach to styling elements.
Old Usage:
style := elem.Style{
styles.BackgroundColor: "#fff",
styles.Color: "#000",
}
New Usage:
style := styles.Props{
styles.BackgroundColor: "#fff",
styles.Color: "#000",
}
Action Required: Replace all instances of elem.Style
with styles.Props
.
3. Deprecation of ApplyStyle
and Introduction of ToInline
The ApplyStyle
method, which was used to set style attributes directly on elements, has been deprecated to promote a more streamlined API. We are introducing the ToInline
method for the styles.Props
type to convert style properties to inline CSS strings more explicitly.
Old Usage with ApplyStyle
:
divStyle := elem.Style{
styles.BackgroundColor: "#f4f4f4",
// ...other styles
}
div := elem.Div(elem.Attrs{
attrs.Style: elem.ApplyStyle(divStyle),
})
New Usage with ToInline
:
divStyle := elem.Style{
styles.BackgroundColor: "#f4f4f4",
// ...other styles
}
div := elem.Div(styles.Props{
attrs.Style: divStyle.ToInline(),
})
Action Required: Migrate all usages of ApplyStyle
to use the ToInline
method on styles.Props
and set the resulting string with the attrs.Style
key when defining element attributes.