Skip to content

Commit c363bdf

Browse files
docs(components): document factory-helper pattern for cleaner call sites (#195)
Adds a "Factory Helpers for Cleaner Call Sites" subsection to the Components guide, covering the `static class Components { ... }` + `using static` pattern that collapses `Component<T, TProps>(new(...))` to a JSX-like `T(args)` call. Includes a runnable snippet and naming conventions. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c4ab2bb commit c363bdf

5 files changed

Lines changed: 77 additions & 0 deletions

File tree

docs/_pipeline/apps/components/App.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ public override Element Render()
9797
}
9898
// </snippet:function-component>
9999

100+
// <snippet:factory-helpers>
101+
static class Components
102+
{
103+
public static ComponentElement Alert(string title, string message,
104+
string severity = "info") =>
105+
Component<global::Alert, AlertProps>(new(title, message, severity));
106+
}
107+
// </snippet:factory-helpers>
108+
100109
// <snippet:composition>
101110
class ComponentsApp : Component
102111
{

docs/_pipeline/templates/components.md.dt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,37 @@ changed structurally, the child skips its `Render()` call.
4747
Access props via `Props.PropertyName` inside `Render()`. The parent sets
4848
props by assigning the `Props` property when creating the component instance.
4949

50+
## Factory Helpers for Cleaner Call Sites
51+
52+
`Component<T, TProps>(new(...))` reads heavily at the call site, especially
53+
when nested in an element tree. The idiomatic Reactor pattern is to wrap each
54+
class component in a free-function factory that matches the rest of the DSL:
55+
56+
```csharp snippet="components/factory-helpers"
57+
```
58+
59+
With `using static Components;` at the top of the consuming file, the call
60+
site collapses to a normal function call:
61+
62+
| Before | After |
63+
|-------------------------------------------------------|--------------------------------------|
64+
| `Component<Alert, AlertProps>(new("Saved", "Done"))` | `Alert("Saved", "Done")` |
65+
| `Component<Alert, AlertProps>(new("Hi", "x", "warn"))`| `Alert("Hi", "x", "warn")` |
66+
67+
The class `Alert` and the helper method `Alert` coexist in the same scope —
68+
C# resolves `Alert(args)` as a method call and `Component<Alert, ...>` as a
69+
type reference, based on syntactic position.
70+
71+
Conventions:
72+
73+
- **Match the component name.** Helper `Alert` for class `Alert` reads like
74+
JSX: `Alert(...)` instead of `<Alert ... />`.
75+
- **Group helpers in a single static class** named `Components` (or per
76+
feature). One `using static` import per consuming file is plenty.
77+
- **Skip `Create` / `Of` / `New` prefixes.** Reactor's built-in element
78+
factories (`Button`, `TextBlock`, `FlexRow`) all read as bare functions;
79+
user helpers should match that grammar.
80+
5081
## Custom ShouldUpdate
5182

5283
Override `ShouldUpdate` to control when a component re-renders:

docs/guide/components.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,43 @@ changed structurally, the child skips its `Render()` call.
7070
Access props via `Props.PropertyName` inside `Render()`. The parent sets
7171
props by assigning the `Props` property when creating the component instance.
7272

73+
## Factory Helpers for Cleaner Call Sites
74+
75+
`Component<T, TProps>(new(...))` reads heavily at the call site, especially
76+
when nested in an element tree. The idiomatic Reactor pattern is to wrap each
77+
class component in a free-function factory that matches the rest of the DSL:
78+
79+
```csharp
80+
static class Components
81+
{
82+
public static ComponentElement Alert(string title, string message,
83+
string severity = "info") =>
84+
Component<global::Alert, AlertProps>(new(title, message, severity));
85+
}
86+
```
87+
88+
With `using static Components;` at the top of the consuming file, the call
89+
site collapses to a normal function call:
90+
91+
| Before | After |
92+
|-------------------------------------------------------|--------------------------------------|
93+
| `Component<Alert, AlertProps>(new("Saved", "Done"))` | `Alert("Saved", "Done")` |
94+
| `Component<Alert, AlertProps>(new("Hi", "x", "warn"))`| `Alert("Hi", "x", "warn")` |
95+
96+
The class `Alert` and the helper method `Alert` coexist in the same scope —
97+
C# resolves `Alert(args)` as a method call and `Component<Alert, ...>` as a
98+
type reference, based on syntactic position.
99+
100+
Conventions:
101+
102+
- **Match the component name.** Helper `Alert` for class `Alert` reads like
103+
JSX: `Alert(...)` instead of `<Alert ... />`.
104+
- **Group helpers in a single static class** named `Components` (or per
105+
feature). One `using static` import per consuming file is plenty.
106+
- **Skip `Create` / `Of` / `New` prefixes.** Reactor's built-in element
107+
factories (`Button`, `TextBlock`, `FlexRow`) all read as bare functions;
108+
user helpers should match that grammar.
109+
73110
## Custom ShouldUpdate
74111

75112
Override `ShouldUpdate` to control when a component re-renders:
27 Bytes
Loading
62.1 KB
Loading

0 commit comments

Comments
 (0)