|
1 | | -// Code generated by guix. DO NOT EDIT. |
2 | | -package main |
| 1 | +package // Code generated by guix. DO NOT EDIT. |
| 2 | +main |
3 | 3 |
|
4 | 4 | import ( |
5 | 5 | "fmt" |
6 | | - "strconv" |
7 | | - "syscall/js" |
8 | | - |
9 | 6 | "github.com/gaarutyunov/guix/pkg/runtime" |
| 7 | + "syscall/js" |
10 | 8 | ) |
11 | 9 |
|
12 | | -// Counter component that displays a counter value |
13 | | -type Counter struct { |
14 | | - app *runtime.App |
15 | | - currentValue int |
16 | | -} |
17 | | - |
18 | | -func NewCounter() *Counter { |
19 | | - return &Counter{ |
20 | | - currentValue: 0, |
21 | | - } |
22 | | -} |
23 | | - |
24 | | -func (c *Counter) BindApp(app *runtime.App) { |
25 | | - c.app = app |
26 | | -} |
27 | | - |
28 | | -func (c *Counter) Render() *runtime.VNode { |
29 | | - return runtime.Div( |
30 | | - runtime.Class("counter-display"), |
31 | | - runtime.Span( |
32 | | - runtime.Class("counter-value"), |
33 | | - runtime.Text(fmt.Sprintf("Counter: %d", c.currentValue)), |
34 | | - ), |
35 | | - ) |
36 | | -} |
37 | | - |
38 | | -func (c *Counter) Mount(parent js.Value) { |
39 | | - runtime.Mount(c.Render(), parent) |
40 | | -} |
41 | | - |
42 | | -func (c *Counter) Unmount() { |
| 10 | +type CounterProps struct { |
| 11 | + CounterChannel chan int |
43 | 12 | } |
| 13 | +type CounterOption func(*Counter) |
44 | 14 |
|
45 | | -func (c *Counter) Update() { |
46 | | - if c.app != nil { |
47 | | - c.app.Update() |
| 15 | +func WithCounterChannel(v chan int) CounterOption { |
| 16 | + return func(c *Counter) { |
| 17 | + c.CounterChannel = v |
48 | 18 | } |
49 | 19 | } |
50 | 20 |
|
51 | | -// App component |
52 | | -type App struct { |
53 | | - app *runtime.App |
54 | | - counter chan int |
55 | | - counterComp *Counter |
56 | | - currentValue int |
| 21 | +type Counter struct { |
| 22 | + app *runtime.App |
| 23 | + CounterChannel chan int |
| 24 | + currentCounterChannel int |
57 | 25 | } |
58 | 26 |
|
59 | | -func NewApp() *App { |
60 | | - app := &App{ |
61 | | - counter: make(chan int, 10), // Buffered channel |
62 | | - currentValue: 0, |
| 27 | +func NewCounter(opts ...CounterOption) *Counter { |
| 28 | + c := &Counter{} |
| 29 | + for _, opt := range opts { |
| 30 | + opt(c) |
63 | 31 | } |
64 | | - // Create Counter component once |
65 | | - app.counterComp = NewCounter() |
66 | | - return app |
| 32 | + return c |
67 | 33 | } |
68 | | - |
69 | | -func (c *App) BindApp(app *runtime.App) { |
| 34 | +func (c *Counter) BindApp(app *runtime.App) { |
70 | 35 | c.app = app |
71 | | - c.counterComp.BindApp(app) |
72 | | - // Start listening to the counter channel |
73 | | - c.startChannelListener() |
| 36 | + if c.CounterChannel != nil { |
| 37 | + c.startCounterChannelListener() |
| 38 | + } |
74 | 39 | } |
75 | | - |
76 | | -// startChannelListener listens for values on the channel and triggers re-renders |
77 | | -func (c *App) startChannelListener() { |
| 40 | +func (c *Counter) startCounterChannelListener() { |
78 | 41 | go func() { |
79 | | - for val := range c.counter { |
80 | | - c.currentValue = val |
81 | | - c.counterComp.currentValue = val |
| 42 | + for val := range c.CounterChannel { |
| 43 | + c.currentCounterChannel = val |
82 | 44 | if c.app != nil { |
83 | 45 | c.app.Update() |
84 | 46 | } |
85 | 47 | } |
86 | 48 | }() |
87 | 49 | } |
88 | | - |
89 | | -func (c *App) Render() *runtime.VNode { |
90 | | - return runtime.Div( |
91 | | - runtime.Class("app-container"), |
92 | | - runtime.H1(runtime.Text("Counter Example")), |
93 | | - runtime.Div( |
94 | | - runtime.Class("input-group"), |
95 | | - runtime.Input( |
96 | | - runtime.Type("number"), |
97 | | - runtime.Placeholder("Enter a number"), |
98 | | - runtime.Value(fmt.Sprint(c.currentValue)), |
99 | | - runtime.ID("counter-input"), |
100 | | - runtime.OnInput(func(e runtime.Event) { |
101 | | - // Parse the input value and send to channel |
102 | | - value := e.Target.Value |
103 | | - if n, err := strconv.Atoi(value); err == nil { |
104 | | - // Non-blocking send |
105 | | - select { |
106 | | - case c.counter <- n: |
107 | | - default: |
108 | | - // Channel full, skip |
109 | | - } |
110 | | - } |
111 | | - }), |
112 | | - ), |
113 | | - ), |
114 | | - c.counterComp.Render(), |
115 | | - ) |
| 50 | +func (c *Counter) Render() *runtime.VNode { |
| 51 | + return runtime.Div(runtime.Class("counter-display"), runtime.Span(runtime.Class("counter-value"), runtime.Text("Counter: "+fmt.Sprint(c.currentCounterChannel)))) |
116 | 52 | } |
117 | | - |
118 | | -func (c *App) Mount(parent js.Value) { |
| 53 | +func (c *Counter) Mount(parent js.Value) { |
119 | 54 | runtime.Mount(c.Render(), parent) |
120 | 55 | } |
121 | | - |
122 | | -func (c *App) Unmount() { |
123 | | - if c.counter != nil { |
124 | | - close(c.counter) |
125 | | - } |
| 56 | +func (c *Counter) Unmount() { |
126 | 57 | } |
127 | | - |
128 | | -func (c *App) Update() { |
| 58 | +func (c *Counter) Update() { |
129 | 59 | if c.app != nil { |
130 | 60 | c.app.Update() |
131 | 61 | } |
|
0 commit comments