Skip to content

Instantly share code, notes, and snippets.

@alecthomas
Last active November 8, 2019 07:37
Show Gist options
  • Save alecthomas/543b194106b3de16bda48b26b96c76c8 to your computer and use it in GitHub Desktop.
Save alecthomas/543b194106b3de16bda48b26b96c76c8 to your computer and use it in GitHub Desktop.
+
+ <div class="page">
+ <ul class="tabs">
+ <li class="tab" onclick="{TabChanged Title}">Hello</li>
+<li class="tab" onclick="{TabChanged Title}">Goodbye</li>
+
+ </ul>
+ <div class="content">
+ <p>hello world</p>
+ </div>
+ </div>
+
received event main.TabChanged{Tab:"Hello"}
<div class="page">
<ul class="tabs">
- <li class="tab" onclick="{TabChanged Title}">Hello</li>
+ <li class="tab selected" onclick="{TabChanged Title}">Hello</li>
<li class="tab" onclick="{TabChanged Title}">Goodbye</li>
</ul>
<div class="content">
<p>hello world</p>
</div>
</div>
received event main.TabChanged{Tab:"Goodbye"}
<div class="page">
<ul class="tabs">
- <li class="tab selected" onclick="{TabChanged Title}">Hello</li>
-<li class="tab" onclick="{TabChanged Title}">Goodbye</li>
+ <li class="tab" onclick="{TabChanged Title}">Hello</li>
+<li class="tab selected" onclick="{TabChanged Title}">Goodbye</li>
</ul>
<div class="content">
- <p>hello world</p>
+ <p>goodbye</p>
</div>
</div>
package main
import (
"fmt"
"time"
"github.com/alecthomas/kong"
. "github.com/alecthomas/goo"
)
type Tab interface {
Component
Title() string
}
type TabChanged struct {
Tab string
}
type Tabs struct {
Selected string
Tabs []Tab
}
func (t *Tabs) Render() Renderable {
titles := Fragments{}
for _, tab := range t.Tabs {
cls := "tab"
if tab.Title() == t.Selected {
cls += " selected"
}
titles.Add("<li class=\"{class}\" onClick=\"{TabChanged Title}\">{Title}</li>\n",
tab, Context{"class": cls})
}
var selected Renderable = Fragment("")
for _, tab := range t.Tabs {
if tab.Title() == t.Selected || t.Selected == "" {
selected = tab.Render()
break
}
}
return Fragment(`
<div class="page">
<ul class="tabs">
{titles}
</ul>
<div class="content">
{selected}
</div>
</div>
`, Context{
"selected": selected,
"titles": titles,
}, t)
}
type DefaultTab struct {
Name string
Text string
}
func (i *DefaultTab) Title() string {
return i.Name
}
func (i *DefaultTab) Render() Renderable {
return Fragment("<p>{Text}</p>", i)
}
var cli struct{}
type Application struct {
Tabs []Tab
Selected string
}
func (a *Application) View() string {
return "<Tabs Tabs={Tabs} Selected={Selected} />"
}
func (a *Application) Schema() ([]Component, []Event) {
return []Component{&Tabs{}}, []Event{TabChanged{}}
}
func (a *Application) Receive(event Event) error {
fmt.Printf("received event %#v\n", event)
switch event := event.(type) {
case TabChanged:
a.Selected = event.Tab
default:
return fmt.Errorf("unsupported event type %T", event)
}
return nil
}
func main() {
ctx := kong.Parse(&cli)
engine := New(&Application{
Tabs: []Tab{
&DefaultTab{Name: "Hello", Text: "hello world"},
&DefaultTab{Name: "Goodbye", Text: "goodbye"},
}})
go func() {
err := engine.Run()
ctx.FatalIfErrorf(err)
}()
time.Sleep(time.Millisecond * 500)
err := engine.Emit("li:nth-child(1)", "onclick")
ctx.FatalIfErrorf(err)
time.Sleep(time.Millisecond * 500)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment