Usage with Phoenix templates
If you find a Moon component you want to use in your existing non-surface templates the recommended way is to replace the live views (or components) that will use the desired component with their Surface's counterparts. See Surface guides
Another solution is to use Moon helpers for rendering components in PhoenixLiveView templates, i.e. using ~H or in *.heex files, is partially supported, however, this approach is limited and mostly not recommended. Keep in mind that Surface extends Liveview, adding extra features like slots and contexts, that are partially supported by helpers.
Examples
Imagine you want to insert Button component to a template. Using Surface your code will look like
alias Moon.Components.Button
def render(assigns) do
~F"""
...
<Button variant="secondary">Secondary</Button>
...
"""
end
The same with LiveView only
alias Moon.Components.Button
import Moon.Helpers.MoonRender
def render(assigns) do
~H"""
...
<.moon module={Button} variant="secondary">Secondary</.moon>
# or, if you wish more explicit naming - use for stateless component
<.surface_component module={Button} variant="secondary">Secondary</.surface_component>
...
"""
end
Please note that surface_component function can render only stateless component. For stateful one you should use surface_live_component function. And moon function can be used for both types of components.
Context
Context usage is a bit tricky. You have to pass it as a Map to the __context__ attribute. And it will not be populated to the child components within template. See examples
# with Surface
def render(assigns) do
~F"""
...
<Context put={locale: @locale}>
<Button variant="secondary">Secondary</Button>
</Context>
...
"""
end
# without Surface
def render(assigns) do
~H"""
...
<.moon module={Button}
variant="secondary"
__context__={%{locale: @locale}}
>
Secondary
</.moon>
...
"""
end