diff --git a/Taskfile.yml b/Taskfile.yml
index 86e4976..7efea7f 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -39,7 +39,7 @@ tasks:
lint:go:
desc: Run golangci-lint
cmds:
- - golangci-lint run
+ - go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.2 run
publish:
desc: Publish a version
@@ -56,7 +56,7 @@ tasks:
desc: Run goimports
cmds:
- go mod tidy
- - goimports -w -local github.com/will-wow/typed-htmx-go .
+ - go run golang.org/x/tools/cmd/goimports@v0.18.0 -w -local github.com/will-wow/typed-htmx-go .
fmt:prettier:
desc: Run prettier on non-go files
diff --git a/hx/hx.go b/hx/hx.go
index ecb6147..49d27f6 100644
--- a/hx/hx.go
+++ b/hx/hx.go
@@ -56,6 +56,9 @@ func (hx *HX) String() string {
return strings.Join(attributes, " ")
}
+// A StandardCSSSelector is any valid CSS selector, like #element or `.class > button`.
+type StandardCSSSelector string
+
// Boost allows you to “boost” normal anchors and form tags to use AJAX instead. This has the [nice fallback] that, if the user does not have javascript enabled, the site will continue to work.
//
// For anchor tags, clicking on the anchor will issue a GET request to the url specified in the href and will push the url so that a history entry is created. The target is the
tag, and the innerHTML swap strategy is used by default. All of these can be modified by using the appropriate attributes, except the click trigger.
@@ -274,8 +277,8 @@ func (hx *HX) PushURLPath(url string) *HX {
// HTMX Attribute: [hx-select]
//
// [hx-select]: https://htmx.org/attributes/hx-select/
-func (hx *HX) Select(selector string) *HX {
- return hx.set(Select, selector)
+func (hx *HX) Select(selector StandardCSSSelector) *HX {
+ return hx.set(Select, string(selector))
}
// SelectOOB allows you to select content from a response to be swapped in via an out-of-band swap.
@@ -324,12 +327,12 @@ func (hx *HX) Select(selector string) *HX {
// HTMX Attribute: [hx-select-oob]
//
// [hx-select-oob]: https://htmx.org/attributes/hx-select-oob/
-func (hx *HX) SelectOOB(selectors ...string) *HX {
- return hx.set(SelectOOB, strings.Join(selectors, ","))
+func (hx *HX) SelectOOB(selectors ...StandardCSSSelector) *HX {
+ return hx.set(SelectOOB, joinStringLikes(selectors, ","))
}
type SelectOOBStrategy struct {
- Selector string
+ Selector StandardCSSSelector
Strategy swap.Strategy
}
@@ -368,7 +371,7 @@ func (hx *HX) SelectOOBWithStrategy(selectors ...SelectOOBStrategy) *HX {
values := make([]string, len(selectors))
for i, s := range selectors {
if s.Strategy == "" {
- values[i] = s.Selector
+ values[i] = string(s.Selector)
} else {
values[i] = fmt.Sprintf("%s:%s", s.Selector, s.Strategy)
}
@@ -489,115 +492,32 @@ func (hx *HX) SwapOOBWithStrategy(strategy swap.Strategy) *HX {
// HTMX Attribute: [hx-swap-oob]
//
// [hx-swap-oob]: https://htmx.org/attributes/hx-swap-oob
-func (hx *HX) SwapOOBSelector(strategy swap.Strategy, selector string) *HX {
- return hx.set(SwapOOB, fmt.Sprintf("%s:%s", strategy, selector))
+func (hx *HX) SwapOOBSelector(strategy swap.Strategy, extendedSelector string) *HX {
+ return hx.set(SwapOOB, fmt.Sprintf("%s:%s", strategy, extendedSelector))
}
-// Target allows you to target a different element for swapping than the one issuing the AJAX request. The value of this attribute can be:
-//
-// - A CSS query selector of the element to target.
-// - this which indicates that the element that the hx-target attribute is on is the target.
-// - closest which will find the closest ancestor element or itself, that matches the given CSS selector (e.g. closest tr will target the closest table row to the element).
-// - find which will find the first child descendant element that matches the given CSS selector.
-// - next which resolves to element.nextElementSibling
-// - next which will scan the DOM forward for the first element that matches the given CSS selector. (e.g. next .error will target the closest following sibling element with error class)
-// - previous which resolves to element.previousElementSibling
-// - previous which will scan the DOM backwards for the first element that matches the given CSS selector. (e.g previous .error will target the closest previous sibling with error class)
-//
-// For targeting a special target like `this`, see [HX.TargetNonStandardSelector()].
-//
-// For targeting finding the nearest element, see [HX.TargetRelative()].
-//
-// Here is an example that targets a div:
-//
-//
-//
-//
-//
-//
-// The response from the /register url will be appended to the div with the id response-div.
-//
-// # Notes
-//
-// hx-target is inherited and can be placed on a parent element
-//
-// HTMX Attribute: [hx-target]
-//
-// [hx-target]: https://htmx.org/attributes/hx-target
-func (hx *HX) Target(selector string) *HX {
- return hx.set(Target, selector)
-}
-
-// A TargetNonStandardSelector is a special HTMX target for swapping.
-type TargetNonStandardSelector string
+type TargetSelector string
const (
- TargetThis TargetNonStandardSelector = "this" // indicates that the element that the hx-target attribute is on is the target.
- TargetNext TargetNonStandardSelector = "next" // resolves to element.nextElementSibling
- TargetPrevious TargetNonStandardSelector = "previous" // resolves to element.previousElementSibling
+ TargetThis TargetSelector = "this" // indicates that the element that the hx-target attribute is on is the target.
+ TargetNext TargetSelector = "next" // resolves to element.nextElementSibling
+ TargetPrevious TargetSelector = "previous" // resolves to element.previousElementSibling
)
-// TargetNonStandard allows you to target a different element for swapping than the one issuing the AJAX request. The value of this attribute can be:
-//
-// - this which indicates that the element that the hx-target attribute is on is the target.
-// - next which resolves to element.nextElementSibling
-// - previous which resolves to element.previousElementSibling
-//
-// For targeting with a general selector target, see [HX.Target()].
-//
-// For targeting finding the nearest element, see [HX.TargetRelative()].
-//
-// This example uses hx-target="this" to make a link that updates itself when clicked:
-//
-// New link
-//
-// # Notes
-//
-// hx-target is inherited and can be placed on a parent element
-//
-// HTMX Attribute: [hx-target]
-//
-// [hx-target]: https://htmx.org/attributes/hx-target
-func (hx *HX) TargetNonStandard(target TargetNonStandardSelector) *HX {
- return hx.set(Target, string(target))
-}
-
-// A SelectorModifier is a relative modifier to a CSS selector. This is used for most "extended selectors".
-type SelectorModifier string
-
-const (
- SelectorClosest SelectorModifier = "closest" // find the closest ancestor element or itself, that matches the given CSS selector
- SelectorFind SelectorModifier = "find" // find the first child descendant element that matches the given CSS selector
- SelectorNext SelectorModifier = "next" // scan the DOM forward for the first element that matches the given CSS selector. (e.g. next .error will target the closest following sibling element with error class)
- SelectorPrevious SelectorModifier = "previous" // scan the DOM backwards for the first element that matches the given CSS selector. (e.g previous .error will target the closest previous sibling with error class)
-)
+var TargetRelative = makeRelativeSelector[SelectorModifier, TargetSelector]()
-// TargetRelative allows you to target a different element for swapping than the one issuing the AJAX request, and find the target relative to the current element. The value of this attribute can be:
-//
-// - closest which will find the closest ancestor element or itself, that matches the given CSS selector (e.g. closest tr will target the closest table row to the element).
-// - find which will find the first child descendant element that matches the given CSS selector.
-// - next which will scan the DOM forward for the first element that matches the given CSS selector. (e.g. next .error will target the closest following sibling element with error class)
-// - previous which will scan the DOM backwards for the first element that matches the given CSS selector. (e.g previous .error will target the closest previous sibling with error class)
+// Target allows you to target a different element for swapping than the one issuing the AJAX request.
//
-// For targeting a special target like `this`, see [HX.TargetElement()].
+// You can pass an extended selector to this method, using [RelativeSelector].
//
-// Here is an example that targets the previous div by ID:
+// Here is an example that targets a div:
//
//
-//
Not me
//
//
//
//
-// The response from the /register url will be appended to the first previous div with the id response-div.
+// The response from the /register url will be appended to the div with the id response-div.
//
// # Notes
//
@@ -614,8 +534,8 @@ const (
// HTMX Attribute: [hx-target]
//
// [hx-target]: https://htmx.org/attributes/hx-target
-func (hx *HX) TargetRelative(modifier SelectorModifier, selector string) *HX {
- return hx.set(Target, fmt.Sprintf("%s %s", modifier, selector))
+func (hx *HX) Target(extendedSelector TargetSelector) *HX {
+ return hx.set(Target, string(extendedSelector))
}
// Trigger allows you to specify what event triggers an AJAX request.
@@ -769,13 +689,23 @@ func (hx *HX) Disable() *HX {
return hx.set(Disable, true)
}
+type DisabledEltModifier string
+
+const DisabledEltClosest DisabledEltModifier = "closest"
+
+type DisabledEltSelector string
+
+const DisabledEltThis DisabledEltSelector = "this"
+
+var DisabledEltRelative = makeRelativeSelector[DisabledEltModifier, DisabledEltSelector]()
+
// DisabledElt allows you to specify elements that will have the disabled attribute added to them for the duration of the request.
//
// The value of this attribute is a CSS query selector of the element or elements to apply the class to, or the keyword closest, followed by a CSS selector, which will find the closest ancestor element or itself, that matches the given CSS selector (e.g. closest tr), or the keyword this
//
// Here is an example with a button that will disable itself during a request:
//
-//