Repository navigation
v0.11.0
v0.11.0 — Keyed components: one instance of many
A component rendered once per item, such as a table row or a card, now gets an id per instance, and a request for one instance tells Props which item it wants. (#41)
func Key(ctx context.Context, v any, key string) (string, error) // "list-row--s3"
func KeyTarget(ctx context.Context, v any, key string) (string, error) // "#list-row--s3"
func (sp *StructPages) Key(v any, key string) (string, error)
func (sp *StructPages) KeyTarget(v any, key string) (string, error)
func KeyOf(t RenderTarget) string // "" when the target isn't keyedRegister the filters in gsx.toml:
key = "github.com/jackielii/structpages.Key"
keytarget = "github.com/jackielii/structpages.KeyTarget"<tr id={ Page.Row |> key(row.ID.String()) }>
<button hx-get={ Page{} |> url } hx-target={ Page.Row |> keytarget(row.ID.String()) } hx-swap="outerHTML">Reload</button>
</tr>case t.Is(p.Row):
id, err := uuid.Parse(structpages.KeyOf(t)) // the key is client input: parse it, then authorise itLike React's key, the key is the item's identity. Unlike React's, Props can read it back.
- Id format: the component's id, then
--, then the key. Bytes outside[A-Za-z0-9-](_included) are written as_XX, so the id needs no CSS escaping andKeyOfreturns exactly the key you passed. - Errors: an empty key, or a plain string in place of a component.
- Matching:
HTMXRenderTargetandHTMXv4RenderTargetmatch a keyed id exactly, never by the loose name and suffix rules.- For one of the served page's components, the target
Isthat component. - For another page's component or a standalone function, the target
Isthat component and Props renders it withRenderComponent. - Either way the target carries the key.
- For one of the served page's components, the target
- Interface unchanged:
RenderTargetis the same. A custom target carries a key by adding aKey() stringmethod.
See Keyed components.
Fixed
- Ids of names with underscores or non-ASCII letters.
camelToKebablowercased every rune withr | 0x20, soRow_Editgot the idrow\x7f-edit, with a DEL control character, andGrößebecamegröÿe. Underscores and hyphens now separate words (Row_Editbecomesrow-edit), and letters of any script are lowercased properly. (#42)
Ids that change
- Names made only of ASCII letters and digits: unchanged. A test checks this against the old function over 100,000 random names.
- Names with
_or non-ASCII letters: fixed as above. Two names that now kebab-case alike in one tree (RowEditandRow_Edit) are reported byMount. - Functions whose package path element has stray hyphens: a function in a package whose last import path element has leading, trailing or doubled hyphens, or a hyphen before a capital (
My-Lib), drops the extra hyphens. Generated ids never contain--. - Hand-written
HX-Targetids of keyed form: this covers anything with a valid key after--, BEM-stylecard--activeincluded. They now match only exactly, so one that used to match a component loosely rendersPage.
Upgrading
Replace hand-built instance ids like f`@{Page.Row |> id}-@{row.ID}` with |> key(row.ID). structpages-lint tools/lint/v0.1.19 flags them.
Full Changelog: v0.10.1...v0.11.0