Files
kjol/go/webui/badges.go

72 lines
1.8 KiB
Go

package webui
import "kjol/vdom"
// Port of web/kit/Badges.tsx.
const (
BadgeGreen = "green"
BadgeRed = "red"
BadgeBlue = "blue"
BadgeAmber = "amber"
BadgeNeutral = "neutral"
BadgeMuted = "muted"
)
const badgeBase = "inline-flex items-center gap-1 text-ss font-semibold py-0.5 px-2 rounded-default whitespace-nowrap"
var badgeColors = map[string]string{
"green": "text-white bg-green-700",
"red": "text-white bg-red-700",
"blue": "text-white bg-sky-800",
"amber": "text-white bg-amber-700",
"neutral": "text-white bg-neutral-500",
"muted": "text-ink-faint bg-transparent",
}
// BadgeProps configures Badge. When OnClick is set the badge renders as a
// <button> (same visuals, interactive).
type BadgeProps struct {
Color string
Pill bool
OnClick func()
Disabled bool
Title string
Class string
}
func badgeClass(p BadgeProps) string {
c := badgeBase
if p.Pill {
c = cx(c, "rounded-full")
}
cc := badgeColors[p.Color]
if cc == "" {
cc = badgeColors["neutral"]
}
c = cx(c, cc)
if p.OnClick != nil {
c = cx(c, "cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed border-0")
}
return cx(c, p.Class)
}
// Badge renders a small status pill (or interactive button when OnClick is set).
func Badge(p BadgeProps, children ...*vdom.VNode) *vdom.VNode {
if p.OnClick != nil {
mods := []vdom.Mod{vdom.Attr("type", "button"), vdom.Attr("class", badgeClass(p)), vdom.On(vdom.EVENT_CLICK, p.OnClick)}
if p.Disabled {
mods = append(mods, vdom.Attr("disabled", "disabled"))
}
if p.Title != "" {
mods = append(mods, vdom.Attr("title", p.Title))
}
return vdom.Button(kids(mods, children)...)
}
mods := []vdom.Mod{vdom.Attr("class", badgeClass(p))}
if p.Title != "" {
mods = append(mods, vdom.Attr("title", p.Title))
}
return vdom.Span(kids(mods, children)...)
}