diff --git a/README.md b/README.md index 386b423..68cd871 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,7 @@ func (Counter) Body(s *g.Scope) g.View { } func main() { - g.Run("Counter", g.Define(func(s *g.Scope) g.View { - return Counter{} - })) + g.Run("Counter", g.Component(Counter{})) } ``` diff --git a/component.go b/component.go index c0be284..fcdc5cf 100644 --- a/component.go +++ b/component.go @@ -25,6 +25,14 @@ type Viewable interface { Body(s *Scope) View } +// Component wraps a Viewable as a View so it can be passed to APIs that take +// a typed View (Run, RunWithConfig, TestRender). Layout constructors accept +// a Viewable directly via their variadic any arguments; this helper is for +// the top-level entry points that cannot. +func Component(v Viewable) View { + return wrapViewable(v) +} + // wrapViewable turns a Viewable into a View by creating a componentNode whose renderFn invokes Body with the current scope. func wrapViewable(v Viewable) View { return &componentNode{ diff --git a/docs-site/content/docs/concepts/viewables.mdx b/docs-site/content/docs/concepts/viewables.mdx index d0fce07..71862d1 100644 --- a/docs-site/content/docs/concepts/viewables.mdx +++ b/docs-site/content/docs/concepts/viewables.mdx @@ -51,6 +51,22 @@ to `VStack`, `List`, or any other constructor. prop if a child view is expensive to construct and you want to defer it (see `NavLink` for an example). +## Passing a Viewable to typed `View` slots + +Layout constructors accept a Viewable directly because their children are +variadic `any`. Top-level entry points like `Run`, `RunWithConfig`, and +`TestRender` take a typed `View`, so a Viewable needs a one-call wrapper: + +```go +func main() { + gova.Run("Counter", gova.Component(Counter{})) +} +``` + +`Component(v Viewable) View` is a thin adapter. It preserves the Viewable's +Body semantics and its reactive scope; all it does is give the compiler a +`View` where it asks for one. + ## When to reach for `Define` `Define` is fine for: diff --git a/docs-site/content/docs/index.mdx b/docs-site/content/docs/index.mdx index 5586ac5..85c5442 100644 --- a/docs-site/content/docs/index.mdx +++ b/docs-site/content/docs/index.mdx @@ -47,7 +47,7 @@ func (Counter) Body(s *Scope) View { } func main() { - Run("Counter", Counter{}) + Run("Counter", Component(Counter{})) } ``` diff --git a/docs-site/content/docs/testing/testrender.mdx b/docs-site/content/docs/testing/testrender.mdx index 759e4c4..5ae449e 100644 --- a/docs-site/content/docs/testing/testrender.mdx +++ b/docs-site/content/docs/testing/testrender.mdx @@ -13,7 +13,7 @@ tree you can query and interact with. ```go func TestCounterIncrements(t *testing.T) { - tree := gova.TestRender(Counter{}) + tree := gova.TestRender(gova.Component(Counter{})) if got := tree.FindText(0).Value; got != "count: 0" { t.Fatalf("unexpected initial text: %q", got)