Label
Renders an accessible label associated with controls.
TailwindCSS
Vanilla JS
package showcase
import (
"github.com/axzilla/templui/internal/components/checkbox"
"github.com/axzilla/templui/internal/components/label"
)
templ CheckboxWithLabel() {
<div class="flex items-center gap-2">
@checkbox.Checkbox(checkbox.Props{
ID: "checkbox-with-label",
})
@label.Label(label.Props{
For: "checkbox-with-label",
}) {
Accept terms and conditions
}
</div>
}
Installation
templui add label
Copy and paste the following code into your project:
package label import "github.com/axzilla/templui/internal/utils" type Props struct { ID string Class string Attributes templ.Attributes For string Error string } templ Label(props ...Props) { {{ var p Props }} if len(props) > 0 { {{ p = props[0] }} } <label if p.ID != "" { id={ p.ID } } if p.For != "" { for={ p.For } } class={ utils.TwMerge( "text-sm font-medium leading-none inline-block", utils.If(len(p.Error) > 0, "text-destructive"), p.Class, ), } data-disabled-style="opacity-50 cursor-not-allowed" { p.Attributes... } > { children... } </label> } var handle = templ.NewOnceHandle() templ Script() { @handle.Once() { <script nonce={ templ.GetNonce(ctx) }> (function() { // IIFE function initLabel(label) { if (!label.hasAttribute('for') || !label.hasAttribute('data-disabled-style')) { return; } const forId = label.getAttribute('for'); const targetElement = forId ? document.getElementById(forId) : null; const disabledStyle = label.getAttribute('data-disabled-style'); if (!disabledStyle) return; const classes = disabledStyle.split(' ').filter(Boolean); function updateStyle() { if (targetElement && targetElement.disabled) { label.classList.add(...classes); } else { label.classList.remove(...classes); } } // Set up mutation observer to detect disabled state changes if (targetElement) { const observer = new MutationObserver(mutations => { for (const mutation of mutations) { if (mutation.type === 'attributes' && mutation.attributeName === 'disabled') { updateStyle(); } } }); observer.observe(targetElement, { attributes: true, attributeFilter: ['disabled'] }); } // Initial style update updateStyle(); } function initAllComponents(root = document) { if (root instanceof Element && root.matches('label[for][data-disabled-style]')) { initLabel(root); } for (const label of root.querySelectorAll('label[for][data-disabled-style]')) { initLabel(label); } } const handleHtmxSwap = (event) => { const target = event.detail.elt if (target instanceof Element) { requestAnimationFrame(() => initAllComponents(target)); } }; initAllComponents(); document.addEventListener('DOMContentLoaded', () => initAllComponents()); document.body.addEventListener('htmx:afterSwap', handleHtmxSwap); document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap); })(); // End of IIFE </script> } }
Update the import paths to match your project setup.