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