Add navigation.PageInfo
- Highlight sidebar entries - Add PageInfo wiring example
This commit is contained in:
parent
0dda9f7767
commit
df7d956874
59
components/navigation/page-info.go
Normal file
59
components/navigation/page-info.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package navigation
|
||||||
|
|
||||||
|
import "github.com/vugu/vugu"
|
||||||
|
|
||||||
|
// PageInfo represents the path of a route.
|
||||||
|
// This is used by navigation components.
|
||||||
|
type PageInfo struct {
|
||||||
|
Path string // URL path.
|
||||||
|
|
||||||
|
Title string // Title that can be defined by the page component.
|
||||||
|
LongTitle string
|
||||||
|
ShortTitle string
|
||||||
|
|
||||||
|
MetaDescription string // Meta description tag that can be defined by the page component.
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPageInfo(path string, component vugu.Builder) PageInfo {
|
||||||
|
var title, longTitle, shortTitle string
|
||||||
|
if c, ok := component.(PageTitleGetter); ok {
|
||||||
|
title, longTitle, shortTitle = c.PageTitle()
|
||||||
|
}
|
||||||
|
|
||||||
|
var metaDescription string
|
||||||
|
if c, ok := component.(PageMetaGetter); ok {
|
||||||
|
metaDescription = c.PageMetaDescription()
|
||||||
|
}
|
||||||
|
|
||||||
|
return PageInfo{
|
||||||
|
Path: path,
|
||||||
|
Title: title,
|
||||||
|
LongTitle: longTitle,
|
||||||
|
ShortTitle: shortTitle,
|
||||||
|
MetaDescription: metaDescription,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageInfoRef struct {
|
||||||
|
*PageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PageInfoRef) PageInfoSet(pageInfo *PageInfo) {
|
||||||
|
p.PageInfo = pageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageInfoSetter interface {
|
||||||
|
PageInfoSet(*PageInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ PageInfoSetter = &PageInfoRef{}
|
||||||
|
|
||||||
|
// Can be implemented by page components to define their page title.
|
||||||
|
type PageTitleGetter interface {
|
||||||
|
PageTitle() (title, longTitle, shortTitle string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can be implemented by page components to define their meta description.
|
||||||
|
type PageMetaGetter interface {
|
||||||
|
PageMetaDescription() (metaDescription string)
|
||||||
|
}
|
@ -1,13 +1,18 @@
|
|||||||
package navigation
|
package navigation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/vugu/vgrouter"
|
"github.com/vugu/vgrouter"
|
||||||
"github.com/vugu/vugu"
|
"github.com/vugu/vugu"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SidebarEntry struct {
|
type SidebarEntry struct {
|
||||||
vgrouter.NavigatorRef
|
vgrouter.NavigatorRef
|
||||||
|
PageInfoRef
|
||||||
|
|
||||||
AttrMap vugu.AttrMap
|
AttrMap vugu.AttrMap
|
||||||
|
classes string // TODO: Use AttrMap to handle classes or something else
|
||||||
|
|
||||||
SymbolSlot vugu.Builder // Slot for the symbol.
|
SymbolSlot vugu.Builder // Slot for the symbol.
|
||||||
DefaultSlot vugu.Builder // Slot for the text and other stuff. Should be a div element!
|
DefaultSlot vugu.Builder // Slot for the text and other stuff. Should be a div element!
|
||||||
@ -18,3 +23,12 @@ type SidebarEntry struct {
|
|||||||
func (c *SidebarEntry) handleClick(event vugu.DOMEvent) {
|
func (c *SidebarEntry) handleClick(event vugu.DOMEvent) {
|
||||||
c.Navigate(c.URL, nil)
|
c.Navigate(c.URL, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *SidebarEntry) Compute(ctx vugu.ComputeCtx) {
|
||||||
|
log.Printf("%v", c.PageInfo)
|
||||||
|
if c.PageInfo != nil && c.PageInfo.Path == c.URL {
|
||||||
|
c.classes = "d3c-1683622560-selected"
|
||||||
|
} else {
|
||||||
|
c.classes = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<button vg-attr="c.AttrMap" class="d3c-1683622560" @click="c.handleClick(event)">
|
<button vg-attr="c.AttrMap" :class='"d3c-1683622560 " + c.classes' @click="c.handleClick(event)">
|
||||||
<vg-comp expr="c.SymbolSlot"></vg-comp><vg-comp expr="c.DefaultSlot"></vg-comp>
|
<vg-comp expr="c.SymbolSlot"></vg-comp><vg-comp expr="c.DefaultSlot"></vg-comp>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@ -15,8 +15,9 @@ func (c *SidebarEntry) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
var vgiterkey interface{}
|
var vgiterkey interface{}
|
||||||
_ = vgiterkey
|
_ = vgiterkey
|
||||||
var vgn *vugu.VGNode
|
var vgn *vugu.VGNode
|
||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "button", Attr: []vugu.VGAttribute{vugu.VGAttribute{Namespace: "", Key: "class", Val: "d3c-1683622560"}}}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(3), Namespace: "", Data: "button", Attr: []vugu.VGAttribute(nil)}
|
||||||
vgout.Out = append(vgout.Out, vgn) // root for output
|
vgout.Out = append(vgout.Out, vgn) // root for output
|
||||||
|
vgn.AddAttrInterface("class", "d3c-1683622560 "+c.classes)
|
||||||
vgn.AddAttrList(c.AttrMap)
|
vgn.AddAttrList(c.AttrMap)
|
||||||
vgn.DOMEventHandlerSpecList = append(vgn.DOMEventHandlerSpecList, vugu.DOMEventHandlerSpec{
|
vgn.DOMEventHandlerSpecList = append(vgn.DOMEventHandlerSpecList, vugu.DOMEventHandlerSpec{
|
||||||
EventType: "click",
|
EventType: "click",
|
||||||
|
File diff suppressed because it is too large
Load Diff
24
root_vgen.go
24
root_vgen.go
@ -46,7 +46,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0x2E9A2E5DC2291CAD^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x96BAA0E9FEE668E^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.Sidebar)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.Sidebar)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -67,7 +67,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0x686B5692725EA031^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x4254F6AC259DD09A^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.ButtonFullscreen)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.ButtonFullscreen)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -94,7 +94,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0x5D38B25E830DE580^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0xD3CD788A91C5BE1E^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -112,7 +112,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
_ = vgparent
|
_ = vgparent
|
||||||
|
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0xE1B3F56AA51B2DB3^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x3293FE053FAB9D98^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LHome)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LHome)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -151,7 +151,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0xEBE260D8ADE95FBE^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x653843F952D5523D^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -169,7 +169,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
_ = vgparent
|
_ = vgparent
|
||||||
|
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0x52BB52A71CBC3F81^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0xF6FF874D2C468F9B^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LStar)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LStar)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -208,7 +208,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0x2AF1551B8C561CD9^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0xB45B66A540EA6780^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -226,7 +226,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
_ = vgparent
|
_ = vgparent
|
||||||
|
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0xFDC8CD2FD0424FED^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x905E00464605D91A^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LInfoCircle)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LInfoCircle)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -276,7 +276,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0xCF5E40696C88BAC9^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x4F533E698911F9BC^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -294,7 +294,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
_ = vgparent
|
_ = vgparent
|
||||||
|
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0xF36D7D0B128ECD49^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x7EE378DF12BAD1B9^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LGlobe)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LGlobe)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -333,7 +333,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
vgn = &vugu.VGNode{Type: vugu.VGNodeType(1), Data: "\n\t\t\t\t\t"}
|
||||||
vgparent.AppendChild(vgn)
|
vgparent.AppendChild(vgn)
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0x1D39634A579B7FEA^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x3E4E9B21705434D6^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*navigation.SidebarEntry)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
@ -351,7 +351,7 @@ func (c *Root) Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {
|
|||||||
_ = vgparent
|
_ = vgparent
|
||||||
|
|
||||||
{
|
{
|
||||||
vgcompKey := vugu.MakeCompKey(0xECD3DBB2A4682E34^vgin.CurrentPositionHash(), vgiterkey)
|
vgcompKey := vugu.MakeCompKey(0x398A831BD02CA2C2^vgin.CurrentPositionHash(), vgiterkey)
|
||||||
// ask BuildEnv for prior instance of this specific component
|
// ask BuildEnv for prior instance of this specific component
|
||||||
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LSettings)
|
vgcomp, _ := vgin.BuildEnv.CachedComponent(vgcompKey).(*icons.LSettings)
|
||||||
if vgcomp == nil {
|
if vgcomp == nil {
|
||||||
|
34
router.go
34
router.go
@ -5,6 +5,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"git.d3nexus.de/Dadido3/D3vugu-components/components/navigation"
|
||||||
"github.com/vugu/vgrouter"
|
"github.com/vugu/vgrouter"
|
||||||
"github.com/vugu/vugu"
|
"github.com/vugu/vugu"
|
||||||
)
|
)
|
||||||
@ -26,31 +27,38 @@ func vuguSetup(buildEnv *vugu.BuildEnv, eventEnv vugu.EventEnv) vugu.Builder {
|
|||||||
// Create root object.
|
// Create root object.
|
||||||
root := &Root{}
|
root := &Root{}
|
||||||
|
|
||||||
|
var pageInfo navigation.PageInfo
|
||||||
|
|
||||||
buildEnv.SetWireFunc(func(b vugu.Builder) {
|
buildEnv.SetWireFunc(func(b vugu.Builder) {
|
||||||
// Make our wire function populate anything that wants a "Navigator".
|
// Make our wire function populate anything that wants a "Navigator".
|
||||||
if c, ok := b.(vgrouter.NavigatorSetter); ok {
|
if c, ok := b.(vgrouter.NavigatorSetter); ok {
|
||||||
c.NavigatorSet(router)
|
c.NavigatorSet(router)
|
||||||
}
|
}
|
||||||
|
if c, ok := b.(navigation.PageInfoSetter); ok {
|
||||||
|
c.PageInfoSet(&pageInfo)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Wire the root component. (Not sure if that is really needed)
|
// Call wire function on root component.
|
||||||
buildEnv.WireComponent(root)
|
buildEnv.WireComponent(root)
|
||||||
|
|
||||||
// Add routes.
|
// Add routes.
|
||||||
router.MustAddRouteExact("/",
|
router.MustAddRouteExact("/", vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
|
||||||
vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
|
root.Body = nil
|
||||||
root.Body = nil
|
}))
|
||||||
}))
|
|
||||||
|
|
||||||
router.MustAddRouteExact("/icons/",
|
router.MustAddRouteExact("/icons", vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
|
||||||
vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
|
root.Body = &PageIcons{}
|
||||||
root.Body = &PageIcons{}
|
}))
|
||||||
}))
|
|
||||||
|
|
||||||
router.SetNotFound(vgrouter.RouteHandlerFunc(
|
router.SetNotFound(vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
|
||||||
func(rm *vgrouter.RouteMatch) {
|
root.Body = nil
|
||||||
root.Body = nil
|
}))
|
||||||
}))
|
|
||||||
|
// add another route at the end that always runs and handles the page info
|
||||||
|
router.MustAddRoute("/", vgrouter.RouteHandlerFunc(func(rm *vgrouter.RouteMatch) {
|
||||||
|
pageInfo = navigation.NewPageInfo(rm.Path, root.Body)
|
||||||
|
}))
|
||||||
|
|
||||||
// Tell the router to listen to the browser changing URLs.
|
// Tell the router to listen to the browser changing URLs.
|
||||||
err := router.ListenForPopState()
|
err := router.ListenForPopState()
|
||||||
|
Loading…
Reference in New Issue
Block a user