lots of stuff
This commit is contained in:
parent
fec5558f28
commit
0dea110ebc
16 changed files with 177 additions and 57 deletions
|
|
@ -19,10 +19,6 @@ func (p *Partial) Render() *Node {
|
||||||
return p.Root
|
return p.Root
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Partial) ToNode() *Node {
|
|
||||||
return p.Root
|
|
||||||
}
|
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Root Renderable
|
Root Renderable
|
||||||
HttpMethod string
|
HttpMethod string
|
||||||
|
|
@ -42,10 +38,6 @@ func NewPageWithHttpMethod(httpMethod string, root Renderable) *Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WrapPartial(ctx *fiber.Ctx, cb func(ctx *fiber.Ctx) *Partial) *Node {
|
|
||||||
return cb(ctx).Root
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPartialWithHeaders(headers *Headers, root Renderable) *Partial {
|
func NewPartialWithHeaders(headers *Headers, root Renderable) *Partial {
|
||||||
return &Partial{
|
return &Partial{
|
||||||
Headers: headers,
|
Headers: headers,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func LiveReloadHandler(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LiveReload() Renderable {
|
func LiveReload() Renderable {
|
||||||
return Div(Get("/livereload"), Trigger("every 200ms"))
|
return Div(Get("/livereload"), Trigger("every 2s"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddLiveReloadHandler(path string, app *fiber.App) {
|
func AddLiveReloadHandler(path string, app *fiber.App) {
|
||||||
|
|
|
||||||
|
|
@ -57,11 +57,12 @@ func (page Builder) renderNode(node *Node) {
|
||||||
|
|
||||||
for _, child := range node.children {
|
for _, child := range node.children {
|
||||||
|
|
||||||
c := child.Render()
|
|
||||||
if child == nil {
|
if child == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c := child.Render()
|
||||||
|
|
||||||
if c.tag == "class" {
|
if c.tag == "class" {
|
||||||
insertAttribute(node, "class", c.value)
|
insertAttribute(node, "class", c.value)
|
||||||
c.tag = FlagSkip
|
c.tag = FlagSkip
|
||||||
|
|
@ -140,6 +141,6 @@ func Render(node Renderable) string {
|
||||||
page.render()
|
page.render()
|
||||||
d := page.builder.String()
|
d := page.builder.String()
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
fmt.Printf("render took %s\n", duration)
|
fmt.Printf("render took %d\n", duration.Microseconds())
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
|
||||||
70
h/tag.go
70
h/tag.go
|
|
@ -81,6 +81,10 @@ func Attribute(key string, value string) Renderable {
|
||||||
return Attributes(map[string]string{key: value})
|
return Attributes(map[string]string{key: value})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TriggerChildren() Renderable {
|
||||||
|
return Attribute("hx-trigger-children", "")
|
||||||
|
}
|
||||||
|
|
||||||
func Disabled() Renderable {
|
func Disabled() Renderable {
|
||||||
return Attribute("disabled", "")
|
return Attribute("disabled", "")
|
||||||
}
|
}
|
||||||
|
|
@ -103,6 +107,7 @@ func CreateTriggers(triggers ...string) []string {
|
||||||
|
|
||||||
type ReloadParams struct {
|
type ReloadParams struct {
|
||||||
Triggers []string
|
Triggers []string
|
||||||
|
Target string
|
||||||
}
|
}
|
||||||
|
|
||||||
func ViewOnLoad(partial func(ctx *fiber.Ctx) *Partial) Renderable {
|
func ViewOnLoad(partial func(ctx *fiber.Ctx) *Partial) Renderable {
|
||||||
|
|
@ -115,10 +120,11 @@ func View(partial func(ctx *fiber.Ctx) *Partial, params ReloadParams) Renderable
|
||||||
return Div(Attributes(map[string]string{
|
return Div(Attributes(map[string]string{
|
||||||
"hx-get": GetPartialPath(partial),
|
"hx-get": GetPartialPath(partial),
|
||||||
"hx-trigger": strings.Join(params.Triggers, ", "),
|
"hx-trigger": strings.Join(params.Triggers, ", "),
|
||||||
|
"hx-target": params.Target,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ViewWithTriggers(partial func(ctx *fiber.Ctx) *Partial, triggers ...string) Renderable {
|
func PartialWithTriggers(partial func(ctx *fiber.Ctx) *Partial, triggers ...string) Renderable {
|
||||||
return Div(Attributes(map[string]string{
|
return Div(Attributes(map[string]string{
|
||||||
"hx-get": GetPartialPath(partial),
|
"hx-get": GetPartialPath(partial),
|
||||||
"hx-trigger": strings.Join(triggers, ", "),
|
"hx-trigger": strings.Join(triggers, ", "),
|
||||||
|
|
@ -126,20 +132,7 @@ func ViewWithTriggers(partial func(ctx *fiber.Ctx) *Partial, triggers ...string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetWithQs(path string, qs map[string]string) Renderable {
|
func GetWithQs(path string, qs map[string]string) Renderable {
|
||||||
u, err := url.Parse(path)
|
return Get(SetQueryParams(path, qs))
|
||||||
if err != nil {
|
|
||||||
return Empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
q := u.Query()
|
|
||||||
|
|
||||||
for s := range qs {
|
|
||||||
q.Add(s, qs[s])
|
|
||||||
}
|
|
||||||
|
|
||||||
u.RawQuery = q.Encode()
|
|
||||||
|
|
||||||
return Get(u.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Post(url string) Renderable {
|
func Post(url string) Renderable {
|
||||||
|
|
@ -239,6 +232,49 @@ func Div(children ...Renderable) Renderable {
|
||||||
return Tag("div", children...)
|
return Tag("div", children...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PushUrlHeader(url string) *Headers {
|
||||||
|
return NewHeaders("HX-Push-Url", url)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CombineHeaders(headers ...*Headers) *Headers {
|
||||||
|
m := make(Headers)
|
||||||
|
for _, h := range headers {
|
||||||
|
for k, v := range *h {
|
||||||
|
m[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &m
|
||||||
|
}
|
||||||
|
|
||||||
|
func CurrentPath(ctx *fiber.Ctx) string {
|
||||||
|
current := ctx.Get("Hx-Current-Url")
|
||||||
|
parsed, err := url.Parse(current)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return parsed.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
func PushQsHeader(ctx *fiber.Ctx, key string, value string) *Headers {
|
||||||
|
current := ctx.Get("Hx-Current-Url")
|
||||||
|
parsed, err := url.Parse(current)
|
||||||
|
if err != nil {
|
||||||
|
return NewHeaders()
|
||||||
|
}
|
||||||
|
return NewHeaders("HX-Push-Url", SetQueryParams(parsed.Path, map[string]string{
|
||||||
|
key: value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHeaders(headers ...string) *Headers {
|
||||||
|
m := make(Headers)
|
||||||
|
for i := 0; i < len(headers); i++ {
|
||||||
|
m[headers[i]] = headers[i+1]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return &m
|
||||||
|
}
|
||||||
|
|
||||||
func Input(inputType string, children ...Renderable) Renderable {
|
func Input(inputType string, children ...Renderable) Renderable {
|
||||||
return &Node{
|
return &Node{
|
||||||
tag: "input",
|
tag: "input",
|
||||||
|
|
@ -331,6 +367,10 @@ func BeforeRequestSetText(text string) Renderable {
|
||||||
return Attribute("hx-on::before-request", `this.innerText = '`+text+`'`)
|
return Attribute("hx-on::before-request", `this.innerText = '`+text+`'`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AfterRequestSetText(text string) Renderable {
|
||||||
|
return Attribute("hx-on::after-request", `this.innerText = '`+text+`'`)
|
||||||
|
}
|
||||||
|
|
||||||
func AfterRequestRemoveAttribute(key string, value string) Renderable {
|
func AfterRequestRemoveAttribute(key string, value string) Renderable {
|
||||||
return Attribute("hx-on::after-request", `this.removeAttribute('`+key+`')`)
|
return Attribute("hx-on::after-request", `this.removeAttribute('`+key+`')`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
h/util.go
17
h/util.go
|
|
@ -46,3 +46,20 @@ func GetQueryParam(ctx *fiber.Ctx, key string) string {
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetQueryParams(href string, qs map[string]string) string {
|
||||||
|
u, err := url.Parse(href)
|
||||||
|
if err != nil {
|
||||||
|
return href
|
||||||
|
}
|
||||||
|
q := u.Query()
|
||||||
|
for key, value := range qs {
|
||||||
|
if value == "" {
|
||||||
|
q.Del(key)
|
||||||
|
} else {
|
||||||
|
q.Set(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.RawQuery = q.Encode()
|
||||||
|
return u.String()
|
||||||
|
}
|
||||||
|
|
|
||||||
20
js/mhtml.js
20
js/mhtml.js
|
|
@ -1,12 +1,30 @@
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
// htmx.logger = function(elt, event, data) {
|
// htmx.logger = function(elt, event, data) {
|
||||||
// if(console) {
|
// if(console) {
|
||||||
// console.log(event);
|
// console.log(elt, event, data);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// onUrlChange(window.location.href);
|
// onUrlChange(window.location.href);
|
||||||
|
|
||||||
|
|
||||||
|
function triggerChildren(event) {
|
||||||
|
const target = event.detail.target
|
||||||
|
const type = event.type
|
||||||
|
if(target && target.children && target.hasAttribute('hx-trigger-children')) {
|
||||||
|
Array.from(target.children).forEach(function(element) {
|
||||||
|
htmx.trigger(element, type);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const events = ['htmx:beforeRequest', 'htmx:afterRequest', 'htmx:responseError', 'htmx:sendError',
|
||||||
|
'htmx:timeout', 'htmx:xhr:abort',
|
||||||
|
'htmx:xhr:loadstart', 'htmx:xhr:loadend', 'htmx:xhr:progress']
|
||||||
|
|
||||||
|
events.forEach(function(event) {
|
||||||
|
document.addEventListener(event, triggerChildren)
|
||||||
|
})
|
||||||
|
|
||||||
window.history.pushState = new Proxy(window.history.pushState, {
|
window.history.pushState = new Proxy(window.history.pushState, {
|
||||||
apply: (target, thisArg, argArray) => {
|
apply: (target, thisArg, argArray) => {
|
||||||
if(argArray.length > 2) {
|
if(argArray.length > 2) {
|
||||||
|
|
|
||||||
18
k6.js
Normal file
18
k6.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import http from 'k6/http';
|
||||||
|
import { sleep } from 'k6';
|
||||||
|
|
||||||
|
export let options = {
|
||||||
|
stages: [
|
||||||
|
{ duration: '1m', target: 100 }, // Ramp-up to 100 RPS over 1 minute
|
||||||
|
{ duration: '10m', target: 100 }, // Stay at 100 RPS for 10 minutes
|
||||||
|
{ duration: '1m', target: 0 }, // Ramp-down to 0 RPS
|
||||||
|
],
|
||||||
|
thresholds: {
|
||||||
|
http_req_duration: ['p(95)<500'], // 95% of requests should be below 500ms
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
http.get('http://localhost:3000/patients');
|
||||||
|
sleep(1 / 100); // Make 100 requests per second
|
||||||
|
}
|
||||||
12
main.go
12
main.go
|
|
@ -36,19 +36,13 @@ func main() {
|
||||||
duration := time.Since(now)
|
duration := time.Since(now)
|
||||||
ctx.Set("X-Response-Time", duration.String())
|
ctx.Set("X-Response-Time", duration.String())
|
||||||
// Log or print the request method, URL, and duration
|
// Log or print the request method, URL, and duration
|
||||||
log.Printf("Request: %s %s took %v", ctx.Method(), ctx.OriginalURL(), duration)
|
log.Printf("Request: %s %s took %dms", ctx.Method(), ctx.OriginalURL(), duration.Milliseconds())
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
f.All("/mhtml/partials*", func(ctx *fiber.Ctx) error {
|
partials.RegisterPartials(f)
|
||||||
partial := partials.GetPartialFromContext(ctx)
|
|
||||||
if partial == nil {
|
|
||||||
return ctx.SendStatus(404)
|
|
||||||
}
|
|
||||||
return h.PartialView(ctx, partial)
|
|
||||||
})
|
|
||||||
|
|
||||||
pages.RegisterPages(f)
|
pages.RegisterPages(f)
|
||||||
|
|
||||||
h.Start(f, h.App{
|
h.Start(f, h.App{
|
||||||
LiveReload: true,
|
LiveReload: true,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"mhtml/h"
|
"mhtml/h"
|
||||||
"mhtml/pages/base"
|
"mhtml/pages/base"
|
||||||
"mhtml/partials/patient"
|
"mhtml/partials/patient"
|
||||||
|
"mhtml/partials/sheet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
||||||
|
|
@ -17,7 +18,13 @@ func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
||||||
h.P("Manage Patients", h.Class("text-lg font-bold")),
|
h.P("Manage Patients", h.Class("text-lg font-bold")),
|
||||||
patient.AddPatientButton(),
|
patient.AddPatientButton(),
|
||||||
),
|
),
|
||||||
h.ViewWithTriggers(patient.List, "load", "patient-added from:body"),
|
h.PartialWithTriggers(patient.List, "load", "patient-added from:body", "every 5s"),
|
||||||
|
h.If(
|
||||||
|
h.GetQueryParam(ctx, "adding") == "true",
|
||||||
|
h.View(patient.AddPatientSheetPartial, h.ReloadParams{
|
||||||
|
Triggers: h.CreateTriggers("load"),
|
||||||
|
Target: sheet.Id,
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -1 +1,16 @@
|
||||||
package partials
|
package partials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"mhtml/h"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterPartials(f *fiber.App) {
|
||||||
|
f.All("/mhtml/partials*", func(ctx *fiber.Ctx) error {
|
||||||
|
partial := GetPartialFromContext(ctx)
|
||||||
|
if partial == nil {
|
||||||
|
return ctx.SendStatus(404)
|
||||||
|
}
|
||||||
|
return h.PartialView(ctx, partial)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial {
|
||||||
if path == "List" || path == "/mhtml/partials/patient.List" {
|
if path == "List" || path == "/mhtml/partials/patient.List" {
|
||||||
return patient.List(ctx)
|
return patient.List(ctx)
|
||||||
}
|
}
|
||||||
if path == "AddPatientSheet" || path == "/mhtml/partials/patient.AddPatientSheet" {
|
if path == "AddPatientSheetPartial" || path == "/mhtml/partials/patient.AddPatientSheetPartial" {
|
||||||
return patient.AddPatientSheet(ctx)
|
return patient.AddPatientSheetPartial(ctx)
|
||||||
}
|
}
|
||||||
if path == "Close" || path == "/mhtml/partials/sheet.Close" {
|
if path == "Close" || path == "/mhtml/partials/sheet.Close" {
|
||||||
return sheet.Close(ctx)
|
return sheet.Close(ctx)
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,11 @@ func Create(ctx *fiber.Ctx) *h.Partial {
|
||||||
LocationName: location,
|
LocationName: location,
|
||||||
})
|
})
|
||||||
|
|
||||||
headers := &map[string]string{
|
headers := h.CombineHeaders(h.PushQsHeader(ctx, "adding", ""), &map[string]string{
|
||||||
"HX-Trigger": "patient-added",
|
"HX-Trigger": "patient-added",
|
||||||
}
|
})
|
||||||
|
|
||||||
return h.NewPartialWithHeaders(headers, h.WrapPartial(ctx, sheet.Close))
|
return h.NewPartialWithHeaders(
|
||||||
|
headers,
|
||||||
|
sheet.Close(ctx))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,26 +40,36 @@ func List(ctx *fiber.Ctx) *h.Partial {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddPatientSheet(ctx *fiber.Ctx) *h.Partial {
|
func AddPatientSheetPartial(ctx *fiber.Ctx) *h.Partial {
|
||||||
return h.NewPartial(sheet.Opened(
|
return h.NewPartialWithHeaders(
|
||||||
|
h.PushQsHeader(ctx, "adding", "true"),
|
||||||
|
AddPatientSheet(h.CurrentPath(ctx)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddPatientSheet(onClosePath string) h.Renderable {
|
||||||
|
return sheet.Opened(
|
||||||
sheet.Props{
|
sheet.Props{
|
||||||
|
OnClosePath: onClosePath,
|
||||||
ClassName: "w-[400px] bg-gray-100 p-4",
|
ClassName: "w-[400px] bg-gray-100 p-4",
|
||||||
Root: h.Div(
|
Root: h.Div(
|
||||||
h.Class("flex flex-col gap-4"),
|
h.Class("flex flex-col gap-4"),
|
||||||
h.P("Add Patient", h.Class("text-lg font-bold")),
|
h.P("Add Patient", h.Class("text-lg font-bold")),
|
||||||
addPatientForm(),
|
addPatientForm(),
|
||||||
),
|
),
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPatientForm() h.Renderable {
|
func addPatientForm() h.Renderable {
|
||||||
return h.Form(
|
return h.Form(
|
||||||
|
h.TriggerChildren(),
|
||||||
h.Post(h.GetPartialPath(Create)),
|
h.Post(h.GetPartialPath(Create)),
|
||||||
h.Class("flex flex-col gap-2"),
|
h.Class("flex flex-col gap-2"),
|
||||||
ui.Input(ui.InputProps{
|
ui.Input(ui.InputProps{
|
||||||
Type: "text",
|
Type: "text",
|
||||||
Label: "Name",
|
Label: "Name",
|
||||||
Name: "name",
|
Name: "name",
|
||||||
|
DefaultValue: "fart",
|
||||||
}),
|
}),
|
||||||
ui.Input(ui.InputProps{
|
ui.Input(ui.InputProps{
|
||||||
Type: "text",
|
Type: "text",
|
||||||
|
|
@ -98,6 +108,6 @@ func AddPatientButton() h.Renderable {
|
||||||
Text: "Add Patient",
|
Text: "Add Patient",
|
||||||
Class: "bg-blue-700 text-white rounded p-2 h-12",
|
Class: "bg-blue-700 text-white rounded p-2 h-12",
|
||||||
Target: sheet.Id,
|
Target: sheet.Id,
|
||||||
Get: h.GetPartialPath(AddPatientSheet),
|
Get: h.GetPartialPath(AddPatientSheetPartial),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package sheet
|
package sheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"mhtml/h"
|
"mhtml/h"
|
||||||
)
|
)
|
||||||
|
|
@ -8,6 +9,7 @@ import (
|
||||||
type Props struct {
|
type Props struct {
|
||||||
ClassName string
|
ClassName string
|
||||||
Root h.Renderable
|
Root h.Renderable
|
||||||
|
OnClosePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
var Id = "#active-modal"
|
var Id = "#active-modal"
|
||||||
|
|
@ -16,7 +18,7 @@ func Opened(props Props) h.Renderable {
|
||||||
return h.Fragment(h.Div(
|
return h.Fragment(h.Div(
|
||||||
h.Class(`fixed top-0 right-0 h-full shadow-lg z-50`,
|
h.Class(`fixed top-0 right-0 h-full shadow-lg z-50`,
|
||||||
h.Ternary(props.ClassName != "", props.ClassName, "w-96 bg-gray-100")),
|
h.Ternary(props.ClassName != "", props.ClassName, "w-96 bg-gray-100")),
|
||||||
closeButton(),
|
closeButton(props),
|
||||||
h.Div(
|
h.Div(
|
||||||
props.Root,
|
props.Root,
|
||||||
)))
|
)))
|
||||||
|
|
@ -27,17 +29,18 @@ func Closed() h.Renderable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Close(ctx *fiber.Ctx) *h.Partial {
|
func Close(ctx *fiber.Ctx) *h.Partial {
|
||||||
return h.NewPartial(
|
return h.NewPartialWithHeaders(
|
||||||
|
h.Ternary(ctx.Query("path") != "", h.PushUrlHeader(ctx.Query("path")), h.NewHeaders()),
|
||||||
h.Swap(ctx, Closed()),
|
h.Swap(ctx, Closed()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeButton() h.Renderable {
|
func closeButton(props Props) h.Renderable {
|
||||||
return h.Div(
|
return h.Div(
|
||||||
h.Class("absolute top-0 right-0 p-3"),
|
h.Class("absolute top-0 right-0 p-3"),
|
||||||
h.Button(
|
h.Button(
|
||||||
h.Class("text-gray-500"),
|
h.Class("text-gray-500"),
|
||||||
h.GetPartial(Close),
|
h.GetPartialWithQs(Close, fmt.Sprintf("path=%s", props.OnClosePath)),
|
||||||
h.Text("X"),
|
h.Text("X"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,10 @@ func Button(props ButtonProps) h.Renderable {
|
||||||
h.Class("flex gap-1 items-center border p-4 rounded cursor-hover", props.Class),
|
h.Class("flex gap-1 items-center border p-4 rounded cursor-hover", props.Class),
|
||||||
h.If(props.Get != "", h.Get(props.Get)),
|
h.If(props.Get != "", h.Get(props.Get)),
|
||||||
h.If(props.Target != "", h.Target(props.Target)),
|
h.If(props.Target != "", h.Target(props.Target)),
|
||||||
|
//h.Attribute("hx-indicator", "#spinner"),
|
||||||
h.IfElse(props.Type != "", h.Type(props.Type), h.Type("button")),
|
h.IfElse(props.Type != "", h.Type(props.Type), h.Type("button")),
|
||||||
|
h.BeforeRequestSetText("Loading..."),
|
||||||
|
h.AfterRequestSetText(props.Text),
|
||||||
text,
|
text,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ func Input(props InputProps) h.Renderable {
|
||||||
h.Class("border p-2 rounded"),
|
h.Class("border p-2 rounded"),
|
||||||
h.If(props.Id != "", h.Id(props.Id)),
|
h.If(props.Id != "", h.Id(props.Id)),
|
||||||
h.If(props.Name != "", h.Name(props.Name)),
|
h.If(props.Name != "", h.Name(props.Name)),
|
||||||
h.If(props.DefaultValue != "", h.Attribute("defaultValue", props.DefaultValue)),
|
h.If(props.DefaultValue != "", h.Attribute("value", props.DefaultValue)),
|
||||||
)
|
)
|
||||||
if props.Label != "" {
|
if props.Label != "" {
|
||||||
return h.Div(
|
return h.Div(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue