100 lines
3.0 KiB
Go
100 lines
3.0 KiB
Go
package ui
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
g "maragu.dev/gomponents"
|
|
h "maragu.dev/gomponents/html"
|
|
"reichard.io/antholume/pkg/ptr"
|
|
"reichard.io/antholume/pkg/sliceutils"
|
|
"reichard.io/antholume/pkg/utils"
|
|
)
|
|
|
|
type PopoverPosition string
|
|
|
|
const (
|
|
// ---- Cornered ----
|
|
|
|
// PopoverTopLeft PopoverPosition = "left-0 top-0 origin-bottom-right -translate-x-full -translate-y-full"
|
|
// PopoverTopRight PopoverPosition = "right-0 top-0 origin-bottom-left translate-x-full -translate-y-full"
|
|
// PopoverBottomLeft PopoverPosition = "left-0 bottom-0 origin-top-right -translate-x-full translate-y-full"
|
|
// PopoverBottomRight PopoverPosition = "right-0 bottom-0 origin-top-left translate-x-full translate-y-full"
|
|
|
|
// ---- Flush ----
|
|
|
|
PopoverTopLeft PopoverPosition = "right-0 -top-1 origin-bottom-right -translate-y-full"
|
|
PopoverTopRight PopoverPosition = "left-0 -top-1 origin-bottom-left -translate-y-full"
|
|
PopoverBottomLeft PopoverPosition = "right-0 -bottom-1 origin-top-right translate-y-full"
|
|
PopoverBottomRight PopoverPosition = "left-0 -bottom-1 origin-top-left translate-y-full"
|
|
|
|
// ---- Centered ----
|
|
|
|
PopoverTopCenter PopoverPosition = "left-1/2 top-0 origin-bottom -translate-x-1/2 -translate-y-full"
|
|
PopoverBottomCenter PopoverPosition = "left-1/2 bottom-0 origin-top -translate-x-1/2 translate-y-full"
|
|
PopoverLeftCenter PopoverPosition = "left-0 top-1/2 origin-right -translate-x-full -translate-y-1/2"
|
|
PopoverRightCenter PopoverPosition = "right-0 top-1/2 origin-left translate-x-full -translate-y-1/2"
|
|
PopoverCenter PopoverPosition = "left-1/2 top-1/2 origin-center -translate-x-1/2 -translate-y-1/2"
|
|
)
|
|
|
|
type PopoverConfig struct {
|
|
Position PopoverPosition
|
|
Classes string
|
|
Dim *bool
|
|
}
|
|
|
|
// AnchoredPopover creates a popover with content anchored to the anchor node.
|
|
// The default position is PopoverBottomRight.
|
|
func AnchoredPopover(anchor, content g.Node, cfg ...PopoverConfig) g.Node {
|
|
// Get Popover Config
|
|
c, _ := sliceutils.First(cfg)
|
|
c.Position = utils.FirstNonZero(c.Position, PopoverBottomRight)
|
|
if c.Dim == nil {
|
|
c.Dim = ptr.Of(false)
|
|
}
|
|
|
|
popoverID := uuid.NewString()
|
|
return h.Div(
|
|
h.Class("relative"),
|
|
h.Label(
|
|
h.Class("cursor-pointer"),
|
|
h.For(popoverID),
|
|
anchor,
|
|
),
|
|
h.Input(
|
|
h.ID(popoverID),
|
|
h.Class("hidden css-button"),
|
|
h.Type("checkbox"),
|
|
),
|
|
Popover(content, c),
|
|
)
|
|
}
|
|
|
|
func Popover(content g.Node, cfg ...PopoverConfig) g.Node {
|
|
// Get Popover Config
|
|
c, _ := sliceutils.First(cfg)
|
|
c.Position = utils.FirstNonZero(c.Position, PopoverCenter)
|
|
if c.Dim == nil {
|
|
c.Dim = ptr.Of(true)
|
|
}
|
|
|
|
wrappedContent := h.Div(h.Class(c.getClasses()), content)
|
|
if !ptr.Deref(c.Dim) {
|
|
return wrappedContent
|
|
}
|
|
|
|
return h.Div(
|
|
h.Div(h.Class("fixed top-0 left-0 bg-black z-40 opacity-50 w-screen h-screen")),
|
|
wrappedContent,
|
|
)
|
|
}
|
|
|
|
func (c *PopoverConfig) getClasses() string {
|
|
return strings.Join([]string{
|
|
"absolute z-50 p-2 transition-all duration-200 rounded shadow-lg",
|
|
"bg-gray-200 dark:bg-gray-600 shadow-gray-500 dark:shadow-gray-900",
|
|
c.Classes,
|
|
string(c.Position),
|
|
}, " ")
|
|
}
|