Add input component for tags
- Change ListBinder interface - Improve ListBindGenericSlice and make it the default - Update input example pagemaster
parent
0766376a7d
commit
4d18fad115
@ -0,0 +1,52 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/vugu/vugu"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// Tags provides a way for the user to add/remove entries from a slice.
|
||||
type Tags struct {
|
||||
AttrMap vugu.AttrMap
|
||||
|
||||
Bind ListBinder // Binds the shown tags to some slice.
|
||||
|
||||
fieldValue string
|
||||
}
|
||||
|
||||
func (c *Tags) keyValuePairs() []ListKeyValuePair {
|
||||
if c.Bind == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.Bind.ListKeyValuePairs()
|
||||
}
|
||||
|
||||
func (c *Tags) handleButtonAdd(event vugu.DOMEvent) {
|
||||
if c.Bind == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't allow empty entries.
|
||||
if c.fieldValue == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't allow duplicate entries.
|
||||
values := c.Bind.ListKeyValuePairs()
|
||||
if slices.ContainsFunc(values, func(k ListKeyValuePair) bool { return k.Value == c.fieldValue }) {
|
||||
return
|
||||
}
|
||||
|
||||
c.Bind.ListAddKeyValuePair(strconv.Itoa(c.Bind.ListLen()), c.fieldValue)
|
||||
}
|
||||
|
||||
func (c *Tags) handleButtonDelete(event vugu.DOMEvent, index int) {
|
||||
if c.Bind == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.Bind.ListDeleteKey(strconv.Itoa(index))
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<div vg-attr='utils.AttributesAppend{AttrMap: c.AttrMap, Classes: "d3c-1685640525"}'>
|
||||
<input:Field :Bind="FieldBindAny{Value: &c.fieldValue}"><input:Button @Click="c.handleButtonAdd(event)"><icons:LPlus></icons:LPlus></input:Button></input:Field>
|
||||
<div vg-for='i, entry := range c.keyValuePairs()' class="d3c-1685640525-tag d3c-color-layer-1 d3c-button-borderless"><span vg-content="entry.Value"></span><input:Button @Click="c.handleButtonDelete(event, i)"><icons:LDelete></icons:LDelete></input:Button></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.d3c-1685640525 {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
/*padding: 0.25em 0.5em;*/
|
||||
/*margin: 0.5em 0;*/
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.d3c-1685640525-tag {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-left: 0.5em;
|
||||
border-radius: 4px;
|
||||
gap: 1em;
|
||||
background-color: var(--d3c-color-background);
|
||||
color: var(--d3c-color-text);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="application/x-go">
|
||||
import (
|
||||
"git.d3nexus.de/Dadido3/D3vugu-components/icons"
|
||||
"git.d3nexus.de/Dadido3/D3vugu-components/utils"
|
||||
)
|
||||
</script>
|
@ -0,0 +1,165 @@
|
||||
package input
|
||||
|
||||
// Code generated by vugu via vugugen. Please regenerate instead of editing or add additional code in a separate file. DO NOT EDIT.
|
||||
|
||||
import "fmt"
|
||||
import "reflect"
|
||||
import "github.com/vugu/vjson"
|
||||
import "github.com/vugu/vugu"
|
||||
import js "github.com/vugu/vugu/js"
|
||||
|
||||
import (
|
||||
"git.d3nexus.de/Dadido3/D3vugu-components/icons"
|
||||
"git.d3nexus.de/Dadido3/D3vugu-components/utils"
|
||||
)
|
||||
|
||||
func (c *Tags) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
||||
|
||||
vgout = &vugu.BuildOut{}
|
||||
|
||||
var vgiterkey interface{}
|
||||
_ = vgiterkey
|
||||
var vgn *vugu.VGNode
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "div", Attr: []vugu.VGAttribute(nil)}
|
||||
vgout.Out = append(vgout.Out, vgn) // root for output
|
||||
vgn.AddAttrList(utils.AttributesAppend{AttrMap: c.AttrMap, Classes: "d3c-1685640525"})
|
||||
{
|
||||
vgparent := vgn
|
||||
_ = vgparent
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t"}
|
||||
vgparent.AppendChild(vgn)
|
||||
{
|
||||
vgcompKey := vugu.MakeCompKey(0x10CE996FF2CD6A72^vgin.CurrentPositionHash(), vgiterkey)
|
||||
// ask BuildEnv for prior instance of this specific component
|
||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*Field)
|
||||
if vgcomp == nil {
|
||||
// create new one if needed
|
||||
vgcomp = new(Field)
|
||||
vgin.BuildEnv.WireComponent(vgcomp)
|
||||
}
|
||||
vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around
|
||||
vgcomp.Bind = FieldBindAny{Value: &c.fieldValue}
|
||||
vgcomp.DefaultSlot = vugu.NewBuilderFunc(func(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
||||
vgn := &vugu.VGNode{Type: vugu.VGNodeType(3)}
|
||||
vgout = &vugu.BuildOut{}
|
||||
vgout.Out = append(vgout.Out, vgn)
|
||||
vgparent := vgn
|
||||
_ = vgparent
|
||||
|
||||
{
|
||||
vgcompKey := vugu.MakeCompKey(0x3C003477D780B326^vgin.CurrentPositionHash(), vgiterkey)
|
||||
// ask BuildEnv for prior instance of this specific component
|
||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*Button)
|
||||
if vgcomp == nil {
|
||||
// create new one if needed
|
||||
vgcomp = new(Button)
|
||||
vgin.BuildEnv.WireComponent(vgcomp)
|
||||
}
|
||||
vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around
|
||||
vgcomp.Click = ClickFunc(func(event ClickEvent) { c.handleButtonAdd(event) })
|
||||
vgcomp.DefaultSlot = vugu.NewBuilderFunc(func(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
||||
vgn := &vugu.VGNode{Type: vugu.VGNodeType(3)}
|
||||
vgout = &vugu.BuildOut{}
|
||||
vgout.Out = append(vgout.Out, vgn)
|
||||
vgparent := vgn
|
||||
_ = vgparent
|
||||
|
||||
{
|
||||
vgcompKey := vugu.MakeCompKey(0xE13B38C095FCE92C^vgin.CurrentPositionHash(), vgiterkey)
|
||||
// ask BuildEnv for prior instance of this specific component
|
||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LPlus)
|
||||
if vgcomp == nil {
|
||||
// create new one if needed
|
||||
vgcomp = new(icons.LPlus)
|
||||
vgin.BuildEnv.WireComponent(vgcomp)
|
||||
}
|
||||
vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around
|
||||
vgout.Components = append(vgout.Components, vgcomp)
|
||||
vgn = &vugu.VGNode{Component: vgcomp}
|
||||
vgparent.AppendChild(vgn)
|
||||
}
|
||||
return
|
||||
})
|
||||
vgout.Components = append(vgout.Components, vgcomp)
|
||||
vgn = &vugu.VGNode{Component: vgcomp}
|
||||
vgparent.AppendChild(vgn)
|
||||
}
|
||||
return
|
||||
})
|
||||
vgout.Components = append(vgout.Components, vgcomp)
|
||||
vgn = &vugu.VGNode{Component: vgcomp}
|
||||
vgparent.AppendChild(vgn)
|
||||
}
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t"}
|
||||
vgparent.AppendChild(vgn)
|
||||
for i, entry := range c.keyValuePairs() {
|
||||
var vgiterkey interface{} = i
|
||||
_ = vgiterkey
|
||||
i := i
|
||||
_ = i
|
||||
entry := entry
|
||||
_ = entry
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "div", Attr: []vugu.VGAttribute{vugu.VGAttribute{Namespace: "", Key: "class", Val: "d3c-1685640525-tag d3c-color-layer-1 d3c-button-borderless"}}}
|
||||
vgparent.AppendChild(vgn)
|
||||
{
|
||||
vgparent := vgn
|
||||
_ = vgparent
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "span", Attr: []vugu.VGAttribute(nil)}
|
||||
vgparent.AppendChild(vgn)
|
||||
vgn.SetInnerHTML(entry.Value)
|
||||
{
|
||||
vgcompKey := vugu.MakeCompKey(0x1FB470EBF2186CBA^vgin.CurrentPositionHash(), vgiterkey)
|
||||
// ask BuildEnv for prior instance of this specific component
|
||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*Button)
|
||||
if vgcomp == nil {
|
||||
// create new one if needed
|
||||
vgcomp = new(Button)
|
||||
vgin.BuildEnv.WireComponent(vgcomp)
|
||||
}
|
||||
vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around
|
||||
vgcomp.Click = ClickFunc(func(event ClickEvent) { c.handleButtonDelete(event, i) })
|
||||
vgcomp.DefaultSlot = vugu.NewBuilderFunc(func(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
||||
vgn := &vugu.VGNode{Type: vugu.VGNodeType(3)}
|
||||
vgout = &vugu.BuildOut{}
|
||||
vgout.Out = append(vgout.Out, vgn)
|
||||
vgparent := vgn
|
||||
_ = vgparent
|
||||
|
||||
{
|
||||
vgcompKey := vugu.MakeCompKey(0xA2FB9E15EF6D040C^vgin.CurrentPositionHash(), vgiterkey)
|
||||
// ask BuildEnv for prior instance of this specific component
|
||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LDelete)
|
||||
if vgcomp == nil {
|
||||
// create new one if needed
|
||||
vgcomp = new(icons.LDelete)
|
||||
vgin.BuildEnv.WireComponent(vgcomp)
|
||||
}
|
||||
vgin.BuildEnv.UseComponent(vgcompKey, vgcomp) // ensure we can use this in the cache next time around
|
||||
vgout.Components = append(vgout.Components, vgcomp)
|
||||
vgn = &vugu.VGNode{Component: vgcomp}
|
||||
vgparent.AppendChild(vgn)
|
||||
}
|
||||
return
|
||||
})
|
||||
vgout.Components = append(vgout.Components, vgcomp)
|
||||
vgn = &vugu.VGNode{Component: vgcomp}
|
||||
vgparent.AppendChild(vgn)
|
||||
}
|
||||
}
|
||||
}
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n"}
|
||||
vgparent.AppendChild(vgn)
|
||||
}
|
||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Data: "style", Attr: []vugu.VGAttribute(nil)}
|
||||
{
|
||||
vgn.AppendChild(&vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t.d3c-1685640525 {\n\t\tdisplay: inline-flex;\n\t\tflex-direction: column;\n\t\tgap: 0.5em;\n\t\t/*padding: 0.25em 0.5em;*/\n\t\t/*margin: 0.5em 0;*/\n\t\tmin-width: 10em;\n\t}\n\n\t.d3c-1685640525-tag {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\t\talign-items: center;\n\t\tpadding-left: 0.5em;\n\t\tborder-radius: 4px;\n\t\tgap: 1em;\n\t\tbackground-color: var(--d3c-color-background);\n\t\tcolor: var(--d3c-color-text);\n\t}\n", Attr: []vugu.VGAttribute(nil)})
|
||||
}
|
||||
vgout.AppendCSS(vgn)
|
||||
return vgout
|
||||
}
|
||||
|
||||
// 'fix' unused imports
|
||||
var _ fmt.Stringer
|
||||
var _ reflect.Type
|
||||
var _ vjson.RawMessage
|
||||
var _ js.Value
|
Loading…
Reference in New Issue