feat(html): add placeholder helper
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
7cbf678738
commit
5fc370b691
4 changed files with 33 additions and 2 deletions
|
|
@ -54,6 +54,7 @@ Accessibility-oriented helpers are also provided for common attribute patterns:
|
|||
- `Dir(node, direction)`
|
||||
- `Alt(node, text)`
|
||||
- `Title(node, text)`
|
||||
- `Placeholder(node, text)`
|
||||
- `Class(node, classes...)`
|
||||
- `AriaHidden(node, hidden)`
|
||||
- `AriaExpanded(node, expanded)`
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ This builds a Header-Content-Footer layout with semantic HTML elements (`<header
|
|||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `node.go` | `Node` interface and all node types: `El`, `Text`, `Raw`, `If`, `Unless`, `Each`, `EachSeq`, `Switch`, `Entitled`, plus `AriaLabel`, `AriaControls`, `AriaHasPopup`, `AriaOwns`, `AriaKeyShortcuts`, `Alt`/`AltText`, `Title`, `AriaBusy`, `AriaLive`, `AriaAtomic`, `AriaDescription`, `AriaDetails`, `AriaErrorMessage`, `AriaRoleDescription`, `AriaDisabled`, `AriaModal`, `AriaChecked`, `AriaInvalid`, `AriaRequired`, `AriaPressed`, `AriaSelected`, `Hidden`, `Disabled`, `Checked`, `Required`, `ReadOnly`, `Selected`, `TabIndex`, and `AutoFocus` helpers |
|
||||
| `node.go` | `Node` interface and all node types: `El`, `Text`, `Raw`, `If`, `Unless`, `Each`, `EachSeq`, `Switch`, `Entitled`, plus `AriaLabel`, `AriaControls`, `AriaHasPopup`, `AriaOwns`, `AriaKeyShortcuts`, `Alt`/`AltText`, `Title`, `Placeholder`, `AriaBusy`, `AriaLive`, `AriaAtomic`, `AriaDescription`, `AriaDetails`, `AriaErrorMessage`, `AriaRoleDescription`, `AriaDisabled`, `AriaModal`, `AriaChecked`, `AriaInvalid`, `AriaRequired`, `AriaPressed`, `AriaSelected`, `Hidden`, `Disabled`, `Checked`, `Required`, `ReadOnly`, `Selected`, `TabIndex`, and `AutoFocus` helpers |
|
||||
| `layout.go` | HLCRF compositor with semantic HTML elements and ARIA roles |
|
||||
| `responsive.go` | Multi-variant breakpoint wrapper (`data-variant` containers, CSS scoping helpers) |
|
||||
| `context.go` | Rendering context: identity, locale, entitlements, i18n service |
|
||||
|
|
@ -52,7 +52,7 @@ This builds a Header-Content-Footer layout with semantic HTML elements (`<header
|
|||
|
||||
## Key Concepts
|
||||
|
||||
**Node tree** -- All renderable units implement `Node`, a single-method interface: `Render(ctx *Context) string`. The library composes nodes into trees using `El()` for elements, `Text()` for translated text, and control-flow constructors (`If`, `Unless`, `Each`, `Switch`, `Entitled`), plus accessibility and visibility helpers such as `AriaLabel()`, `AriaControls()`, `AriaHasPopup()`, `AriaOwns()`, `AriaKeyShortcuts()`, `AriaCurrent()`, `AriaBusy()`, `AriaLive()`, `AriaAtomic()`, `AriaDescription()`, `AriaDetails()`, `AriaErrorMessage()`, `AriaRoleDescription()`, `AriaHidden()`, `Hidden()`, `AriaDisabled()`, `AriaModal()`, `AriaChecked()`, `AriaInvalid()`, `AriaRequired()`, `AriaReadOnly()`, `Disabled()`, `Checked()`, `Required()`, `ReadOnly()`, `Selected()`, `TabIndex()`, and the common HTML attribute helpers `Alt()`, `AltText()`, `Title()`, `ID()`, `For()`, `Class()`, and `AutoFocus()`.
|
||||
**Node tree** -- All renderable units implement `Node`, a single-method interface: `Render(ctx *Context) string`. The library composes nodes into trees using `El()` for elements, `Text()` for translated text, and control-flow constructors (`If`, `Unless`, `Each`, `Switch`, `Entitled`), plus accessibility and visibility helpers such as `AriaLabel()`, `AriaControls()`, `AriaHasPopup()`, `AriaOwns()`, `AriaKeyShortcuts()`, `AriaCurrent()`, `AriaBusy()`, `AriaLive()`, `AriaAtomic()`, `AriaDescription()`, `AriaDetails()`, `AriaErrorMessage()`, `AriaRoleDescription()`, `AriaHidden()`, `Hidden()`, `AriaDisabled()`, `AriaModal()`, `AriaChecked()`, `AriaInvalid()`, `AriaRequired()`, `AriaReadOnly()`, `Disabled()`, `Checked()`, `Required()`, `ReadOnly()`, `Selected()`, `TabIndex()`, and the common HTML attribute helpers `Alt()`, `AltText()`, `Title()`, `Placeholder()`, `ID()`, `For()`, `Class()`, and `AutoFocus()`.
|
||||
|
||||
**HLCRF Layout** -- A five-slot compositor that maps to semantic HTML: `<header>` (H), `<aside>` (L/R), `<main>` (C), `<footer>` (F). The variant string controls which slots render: `"HLCRF"` for all five, `"HCF"` for three, `"C"` for content only. Layouts nest: placing a `Layout` inside another layout's slot produces hierarchical `data-block` paths like `L-0-C-0`.
|
||||
|
||||
|
|
|
|||
10
node.go
10
node.go
|
|
@ -406,6 +406,16 @@ func Title(n Node, text string) Node {
|
|||
return n
|
||||
}
|
||||
|
||||
// node.go: Placeholder sets the placeholder attribute on an element node.
|
||||
// Example: Placeholder(El("input"), "Search by keyword").
|
||||
// An empty value leaves the node unchanged so callers can opt out cleanly.
|
||||
func Placeholder(n Node, text string) Node {
|
||||
if value := trimmedNonEmpty(text); value != "" {
|
||||
return Attr(n, "placeholder", value)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// node.go: AltText is a compatibility alias for Alt.
|
||||
// Example: AltText(El("img"), "Product screenshot").
|
||||
// Prefer Alt for new call sites so the canonical image helper stays predictable.
|
||||
|
|
|
|||
20
node_test.go
20
node_test.go
|
|
@ -663,6 +663,26 @@ func TestTitleHelper_IgnoresWhitespace(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPlaceholderHelper(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
node := Placeholder(El("input"), "Search by keyword")
|
||||
got := node.Render(ctx)
|
||||
want := `<input placeholder="Search by keyword">`
|
||||
if got != want {
|
||||
t.Errorf("Placeholder() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceholderHelper_IgnoresWhitespace(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
node := Placeholder(El("input"), " \t ")
|
||||
got := node.Render(ctx)
|
||||
want := `<input>`
|
||||
if got != want {
|
||||
t.Errorf("Placeholder() with whitespace = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAltTextHelper(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
node := AltText(El("img"), `A "quoted" caption`)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue